1:join线程
线程插队:
控制台输出:
可以看到thread线程在调用了join方法之后,开始进行了“插队”操作,主线程mian要等待thread线程执行完之后再执行。
join()方法有如下三种重载方式(会抛出InterruptedException异常):
(1)join():等待被join的线程执行结束。
(2)join(long millis):等待被join的线程时间最长为millis毫秒数(线程走完就不必再等),不管有没有走完。
(3)join(long millis,int nanos):等待被join的线程最长为millis毫秒数,加上nanos微毫秒。(几乎不用)
2:后台线程(守护线程、精灵线程)
最常见的后台线程就是垃圾回收器了,当然也可以调用setDaemon(true)来给前台线程变为后台线程。
后台线程特征: 如果前台线程全部死亡,JVM主动退出,后台线程自动死亡。需要注意的是,设置前台线程为后台线程,必须在线程调用start()方法之前。
3:睡眠线程
sleep()有两种重载方式(会抛出InterruptedException异常):
(1)sleep(long millis):该线程睡眠millis毫秒,并进入阻塞。这里的millis并不完全准确。
(2)sleep(long millis,long nanos):该线程睡眠millis毫秒加nanos微秒数。(几乎不用)
注意:虽然sleep()方法会让该线程从运行——>阻塞——>就绪。让出时间片给其它线程“抢”,但是当该线程重新获得cpu调度的话,那么并不会重新执行run()方法,而是从睡眠之后的代码开始执行。
4:线程让步:yield()
线程礼让,但是不一定保证礼让成功,因为,yield()方法只是将线程从运行状态转换成就绪状态,重新等待cpu的调度,不能保证下次调度就一定不是刚刚所礼让的线程。 特别需要注意的是,yield()礼让——只有优先级和礼让线程相同或者比礼让线程更高才会获得执行机会。
yield()方法和sleep()方法的区别:
(1)yield()方法没有抛出异常,sleep()方法需要抛出InterruptedException异常。
(2)yield()不能确保一定礼让成功;sleep()能够确保自己“睡眠”,让出cpu执行权限给其它线程。
(3)被yield()的方法把状态从运行到就绪,被sleep()的线程把状态从运行到阻塞。
(4)sleep()有更好的可移植性,通常不建议用yield()方法来控制并发的执行。
5:改变线程优先级setPriority(int newPriority)
每个线程都有线程优先级,默认的优先级是5;
Thread类有三个静态常量优先级:
(1)MAX_PRIORITY:10
(2)MIN_PRIORITY:1
(3)NORM_PRIORITY:5
提醒一下,并不是优先级高的线程就一定先执行,优先级高只是代表着该线程获取cpu的时间片的概率高,先执行的概率高而已。(为了保证程序有较好的可移植性,不建议手动指定线程优先级。因为不同操作系统,线程优先级不一样,windows2000 只有7个优先级)