控制线程
Java提供了一些控制线程的工具方法
join线程
Thread提供了让一个线程等待另一个线程完成的方法----join方法,当在某个程序执行流中调用其他线程的join方法时,该线程将被阻塞,直到被调用join线程执行完为止。
例子:
1 |
|
在该程序中,主线程调用了jt线程的join方法,则主线程会陷入阻塞,直到jt线程执行完成,主线程才会继续运行。
join方法有三种重载形式:
- join():等待被join的线程执行完毕
- join(long millis):等待被join的线程时间最长为millis毫秒,如果在millis毫秒时间后,还没有完成,则不再等待
- join(long millis, int nanos):等待被join的线程执行时间最长为millis毫秒加nanos毫微秒
通常很少使用第三种形式。
后台线程
在多线程中,main线程只是其中一个线程,必须等待所有线程结束后,整个进程才能结束。那么我们可以将一些线程设为后台线程。
后台线程是在后台运行的,其他所有线程结束后,这些后台线程会自动结束,从而整个进程结束。
这些后台线程是为其他线程提供服务的。又称为”守护线程“或者”精灵线程“。
后台线程的特征就是如果所有前台线程死亡,后台线程会自动死亡。
可以调用Thread对象的setDaemon方法来将指定线程设为后台线程,并且必须在start方法之前设置,否则会抛出异常。
前台线程创建的子线程默认为前台线程,后台线程创建的子线程默认为后台线程。
## 线程睡眠:sleep
如果需要将当前正在执行的线程暂停一段时间,进入阻塞状态,可以调用Thread的静态方法sleep方法来实现。sleep方法有两种重载形式。
- static void sleep(long millis):让当前正在执行的线程暂停millis毫秒,并进入阻塞状态,该方法受到系统计时器和线程调度器的精度和准确度的影响。
- static void sleep(long millis, int nanos):当前执行的线程暂停millis毫秒加nanos毫微秒
程序很少使用第二种形式。
当当前线程调用sleep方法进入阻塞状态后,在其睡眠时间段内,该线程不会获得,执行的机会,即使系统中没有其他正在运行的线程,处于睡眠的线程也不会执行。
让线程转入就绪状态:yield
与sleep方法类似,Thread的一个静态方法yield可以使当前线程暂停,但这个方法并不会使线程陷入阻塞,它只是将线程转入就绪状态,等待重新调度。
关于sleep方法和yield方法的区别有:
- sleep方法暂停当前线程后,会给其他线程执行的机会,不会理会其他线程的优先级,但是yield方法只会给优先级相同或更高的线程执行机会
- sleep方法会将线程陷入阻塞状态,经过阻塞时间后才会转入就绪状态,但是yield方法只是强制当前线程进入就绪状态
- sleep方法声明抛出了InterruptException异常,调用sleep方法要么捕捉该异常,要么抛出该异常,而yield方法不会声明抛出任何异常
- sleep方法比yield方法有更好的可移植性,通常不建议使用yield方法控制并发线程的执行
改变线程优先级
每一个线程都有优先级,优先级高的线程会获得更多的执行机会。
每个线程默认的优先级都与创建它的线程拥有相同的优先级,在默认情况,main线程具有普通优先级。
Thread提供了一个方法setPriority(int newPriority),getPriority()方法来设置和获得线程的优先级。其中,setPriority方法参数为一个整数,范围是1~10之间,也可以使用Thread类的三个静态常量。
- MAX_PRIORITY:10
- MIN_PRIORITY: 1
- NORM_PRIORITY: 5