点击此处查看最新的网赚项目教程

Object中的wait、notify、notifyAll,可以用于线程间的通信,核心原理为借助于监视器的入口集与等待集逻辑

通过这三个方法完成线程在指定锁(监视器)上的等待与唤醒,这三个方法是以锁(监视器)为中心的通信方法

除了它们之外,还有用于线程调度、控制的方法,他们是sleepyield、join方法,他们可以用于线程的协作,他们是围绕着线程的调度而来的

sleep方法

有两个版本的sleep方法,看得出来,核心仍旧是native方法

非native方法只是进行了参数校验,接着仍旧是调用的native方法,这个情形与wait是类似的

threadjoin阻塞_threadjoin方法_thread.join

接下来仔细看下,native版本的sleep

在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。

注意:

sleep不会释放锁,不会释放锁,不会释放锁

可以理解为他进入监视器这个房间之后,在这房间里面睡着了

与wait类似的是,sleep也是可中断方法(从方法签名可以看得出来,可能抛出InterruptedException),也就是说如果一个线程正在sleep,如果另外的线程将他中断(调用interrupt方法),将会抛出异常,并且中断状态将会擦除

所以对于sleep方法,要么自己醒来,要么被中断后也会醒来

对于sleep始终有一个超时时间的设置,所以,尽管他是在监视器内睡着了,但是并不会导致死锁,因为他终究是要醒来的

如下,线程休眠500毫秒,主线程50毫秒打印一次状态

ps:sleep方法的调用结果为状态:TIMED_WAITING

threadjoin阻塞_threadjoin方法_thread.join

借助于sleep方法,可以模拟线程的顺序执行

比如下面示例,两个阶段,第二个阶段将在第一个阶段执行之后才会执行

threadjoin阻塞_threadjoin方法_thread.join

thread.join_threadjoin阻塞_threadjoin方法

另外,你应该已经注意到sleep方法都有static修饰,既然是静态方法,在Thread中的惯例就是针对于:当前线程,当前线程,当前线程

yield方法

对于sleep或者wait方法,他们都将进入特定的状态,伴随着状态的切换,也就意味着等待某些条件的发生,才能够继续,比如条件满足,或者到时间等

但是yield方法不涉及这些事情,他针对的是时间片的划分与调度,所以对开发者来说只是临时让一下,让一下他又不会死,就只是再等等

yield方法将会暂停当前正在执行的线程对象,并执行其它线程,他始终都是RUNNABLE状态

threadjoin方法_thread.join_threadjoin阻塞

不过要注意,可以认为yield只是一种建议性的,如果调用了yield方法,对CPU时间片的分配进行了“礼让”,它仍旧有可能继续获得时间片,并且继续执行

所以一次调用yield 并不一定会代表肯定会发生什么

threadjoin阻塞_thread.join_threadjoin方法

借助于while循环以及yield方法,可以看得出来,也能一定程度上达到线程排序等待的效果

thread.join_threadjoin阻塞_threadjoin方法

yield也是静态方法,所以,也是针对于当前线程,当前线程,当前线程。

join方法

三个版本的join方法

threadjoin阻塞_thread.join_threadjoin方法

方法的实现过程,与wait也是非常类似,下面两个版本的方法一个调用join(0),一个参数校验后,调用join(millis),所以根本还是单参数版本的join方法

thread.join_threadjoin方法_threadjoin阻塞

在方法深入介绍前先看个例子

一个线程,循环5次,每次sleep 1s,主线程中打印信息

从结果可以看到,主线程总是在线程执行之后,才会执行,也就是主线程在等待我们创建的这个线程结束,结束了之后才会继续进行

thread.join_threadjoin方法_threadjoin阻塞

thread.join_threadjoin阻塞_threadjoin方法

如果调整下顺序—>start 与 join的先后顺序,再次看下情况,可以发现顺序没有保障了

threadjoin方法_threadjoin阻塞_thread.join

结论:

主线程main中调用启动线程(调用start),然后调用该线程的join方法,可以达到主线程等待工作线程运行结束才执行的效果,并且join要在start调用后

如何做到的?

threadjoin方法_threadjoin阻塞_thread.join

从上面源代码可以看得出来,内部调用了wait方法,所以也能明白为啥join也会抛出InterruptedException了吧

主线程main中调用thread.join()方法,join方法相当于join(0),也就是

while (isAlive()) {

wait(0);

而这个wait(0)就相当于是this.wait(0),this就是我们自己创建的那个线程thread,看看方法的签名是不是有一个synchronized

isAlive()也是this.isAlive(),也就是如果当前线程alive(已经启动,但是未终止),那么将持续等待,等待的临界资源就是我们创建的这个线程对象本身

所以这两行代码的含义就是:

该线程是否还存活?如果存活,调用join的那个线程将会在这个对象上进行等待(进入该线程对象的等待集)

也就是说调用一个线程的join方法,就是在这个线程是等待,这个线程对象就是我们的锁对象(不要疑惑,Object都可以作为锁,Thread实例对象怎么不可以?)

肯定大家很奇怪,既然是等待,wait又不会自己醒来,那不是出问题了吗?

其实线程结束后,会调用this.notifyAll,所以主线程main会被唤醒

如果传递的参数不为0,将会走到下面的分支,或wait指定时长,与上面的逻辑一致,只不过是有指定超时时长而已

long delay = millis – now;

if (delay

———END———
限 时 特 惠: 本站每日持续更新海量各大内部创业教程,一年会员只需98元,全站资源免费下载 点击查看详情
站 长 微 信: cai842612