一:静态方法
●Thread.currentThread()
返回的是对当前正在执行线程对象的引用。线程类的构造方法、静态块是被main线程调用的,而线程类的run()方法才是应用线程自己调用的。this是线程自己,不是main。
package chin.tei.thread;
public class TestThread {
public static void main(String[] args) {
UserThread userThread=new UserThread();
userThread.start();
}
}
class UserThread extends Thread {
static{
System.out.println("静态块的打印:" + Thread.currentThread().getName());
}
public UserThread() {
System.out.println("UserThread----->Begin");
System.out.println("构造方法的打印:" + Thread.currentThread().getName());
System.out.println("this.getName()----->" + this.getName());
System.out.println("UserThread----->end");
}
public void run() {
System.out.println("run----->Begin");
System.out.println("run()方法的打印:" + Thread.currentThread().getName());
System.out.println("this.getName()----->" + this.getName());
System.out.println("run----->end");
}
}
看一下运行结果:
静态块的打印:main
UserThread----->Begin
构造方法的打印:main
this.getName()----->Thread-0
UserThread----->end
run----->Begin
run()方法的打印:Thread-0
this.getName()----->Thread-0
run----->end
●Thread.sleep(
long
millis)
//参数为毫秒
●Thread.
sleep(
long
millis,
int
nanoseconds)
//第一参数为毫秒,第二个参数为纳秒
暂停的线程是Thread.currentThread()返回的线程,sleep只是让出CPU,但是如果该线程持有锁,不会释放,会一直持有(和wait不一样,wait释放锁),sleep后线程进入到阻塞状态(blocking)。
●Thread.yield()
和sleep一样,让出CPU,也不会释放锁,但是yield后该线程进入到就绪状态,这样可能连续抢到CPU再执行。另外,CPU从就绪状态线程队列中只会选择与该线程优先级相同或优先级更高的线程去执行。
二:实例方法
●start()方法
start()用来启动一个线程,当调用start方法后,系统才会开启一个新的线程来执行用户定义的子任务,在这个过程中,会为相应的线程分配需要的资源。
●run()方法
run()方法是不需要用户来调用的,当通过start方法启动一个线程之后,当线程获得了CPU执行时间,便进入run方法体去执行具体的任务。
●isAlive()方法
start()后一直到run()结束或者线程异常退出,就是true;否则就是false。
●getId()方法
getId()的作用是取得线程的唯一标识。在一个Java应用中,有一个long型的全局唯一的线程ID生成器threadSeqNumber,每new出来一个线程都会把这个自增一次,并赋予线程的tid属性,这个是Thread自己做的,用户无法执行一个线程的Id。
●getName和setName方法
我们new一个线程的时候,可以指定该线程的名字,也可以不指定。如果指定,那么线程的名字就是我们自己指定的,getName()返回的也是开发者指定的线程的名字;如果不指定,那么Thread中有一个int型全局唯一的线程初始号生成器threadInitNum,Java先把threadInitNum自增,然后以"Thread-threadInitNum"的方式来命名新生成的线程
●getPriority和setPriority方法
用来获取和设置线程优先级。可以指定1到10,默认是5。
线程优先级特性:
- 继承性
比如A线程启动B线程,则B线程的优先级与A是一样的。 - 规则性
高优先级的线程总是大部分先执行完,但不代表高优先级线程全部先执行完。 - 随机性
优先级较高的线程不一定每一次都先执行完。
●setDaemon和isDaemon方法
用来设置线程是否成为守护线程和判断线程是否是守护线程。
java有两种线程,一种是用户线程(即普通的线程,比如main线程),一种是守护线程(典型的比如GC)。守护线程特殊在虚拟机的离开:如果User Thread全部撤离,那么Daemon Thread也就没啥线程好服务的了,所以虚拟机也就退出了。
- thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个IllegalThreadStateException异常。你不能把正在运行的常规线程设置为守护线程。
- 在Daemon线程中产生的新线程也是Daemon的。(即在Daemon线程中的run方法里的新线程不需要显示的调用setDaemon就是守护线程)
- 不是所有的应用都可以分配给Daemon线程来进行服务,比如读写操作或者计算逻辑。因为在Daemon Thread还没来的及进行操作时,虚拟机可能已经退出了。
线程终止:stop(),suspend()及resume(),destroy()方法是不安全的,已被弃用。
线程终止一般有:
- 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止
- 使用stop方法强行终止线程,但是不推荐使用这个方法,因为stop和suspend及resume一样,都是作废过期的方法,使用他们可能产生不可预料的结果。
- 使用interrupt方法中断线程,但这个不会终止一个正在运行的线程,还需要加入一个判断才可以完成线程的停止。
●join()方法
join方法有三个重载版本:
1
2
3
|
join() //等价于 join(0) 执行该线程的程序会阻塞,一直等到该run()方法结束
join(
long
millis)
//参数为毫秒 执行该线程的程序会阻塞, 但是millis后就会继续执行,不一定需要run()方法结束
join(
long
millis,
int
nanoseconds)
//第一参数为毫秒,第二个参数为纳秒
|
●join()必须放在start()的后面
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}