join:因为是连接,所以需要两个线程,
一、简单功能介绍
1、 正在干活的线程,你想和谁连啊(即对方线程):正在干活方表示这活干不下去了,一定要等别人全部干完才能干。
方法: 调用对方.join()
2、例子:比如正在洗衣服(正在执行线程),这时楼下水管破了,只能自来水公司的人修好水管(对方线程)
即:自来水公司.join()
3、sleepy1.join:正在执行的线程让出Cpu,进入阻塞队里,反正等待sleepy1执行完(即die),才能执行,至于slppy1什么时候能进入Cpu,由调度程序去控制,
sleepy1.interrupt():表示线程都是自然醒,哪么sleepy1线程设置了中断标志,sleepy1进入Cpu执行,但是执行后面的catch 指令,所以Sleepy1线程退出Cpu,表示自己已经die,
两个线程:1个设置中断标志,1个没有,哪么自然睡醒后,全部进入就绪队列,可以入Cpu。
唯一区分:1>就是设置中断标志的线程,直接执行异常处理,退出Cpu
2>未设置中断标志的线程,继续方法里后面的指令。
}
二、例子:文字描述
1、两个睡觉线程,sleep1,sleep2
2、两个连接线程和睡觉线程相连 join1 连 sleep1,join2 连 sleep2
sleep1 睡到自然醒,设置中断标志
sleep2 睡到自然醒,没有设置中断
3、所以本程序有5个线程。
main()线程+sleep1,sleep2,join1,join2 4个线程。
4、执行:先执行main 下面的两个线程,由于这两个程序在new 时调用.start()方法,所以sleep1,2 两线程进入就绪队列。
这俩线程谁先谁后,由调度程序决定,下面例子是sleep1先执行,如果你重新执行一篇,有可能是sleep2或join1()先执行
这个例子主要保证join1,join2 执行顺序,其它线程可先可后。
1》 本例子:main 退出 Cpu,进入就绪队列
2》cpu空,调度程序选择sleep1先占Cpu,----,sleep(1500)-------进入阻塞队列
3》cpu空,调度程序选sleep2占Cpu,----sleep(1500)-----进入阻塞队列
4》cpu空,就绪队列只剩下main()了,-----执行Main()的一条指令,new 时已经调用.start(),-----join1,join2 进入就绪队列
5》main 退出 Cpu,进入就绪队列.
6》cpu空,join1进入cpu,执行 sleep1.join() :表示一定要等到sleep1执行完了且sleep1线程死亡后,我才能执行。
join1----进入阻塞队列
7》cpu空,调度程序选中Main()进入内存,执行sleepy1.interrupt(),标志sleepy1线程中断,且die
8》这时main线程已经没有指令了,cpu空
就绪队列只剩下join2 ()了
这时sleepy1 已经睡醒,进入就绪队列,调度程序选sleepy1入cpu,因为已经设置中断标志,因此直接执行catch后面的语句,这时
sleepy1 死亡。
9》cpu 空。就绪队列只剩下join2 ()了
直接进入Cpu执行:当执行到 sleep2.join() ,需要sleep2干完活自己才能继续干活,----join2 进入阻塞队列
10》cpu空,调度程序调度 阻塞队列的join1()进入就绪队列
就绪队列只剩下join1 ()了,join1线程入cpu,执行,join1执行完。
11》cpu空,就绪队列空
sleepy2已经睡醒: 入就绪队,进cpu执行,由于没中断标志,直接执行未执行完的指令
12》cpu空,就绪队列空,阻塞队列剩下 join2
join2进入就绪队,进cpu执行。
***整个执行完成。
三、例子:图形描述
四、代码 java think上的代码
package concurrency; import static net.mindview.util.Print.*; class Sleeper extends Thread { private int duration; public Sleeper(String name, int sleepTime) { super(name); duration = sleepTime; start(); } public void run() { print(getName() + " run"); try { sleep(duration); } catch (InterruptedException e) { print(getName() + " was interrupted. " + "isInterrupted(): " + isInterrupted()); return; } print(getName() + " has awakened"); } } class Joiner extends Thread { private Sleeper sleeper; public Joiner(String name, Sleeper sleeper) { super(name); this.sleeper = sleeper; start(); } public void run() { print(getName() + " join"); try { sleeper.join(); } catch (InterruptedException e) { print("Interrupted"); } print(getName() + " join completed"); } } public class Joining { public static void main(String[] args) { Sleeper sleepy1 = new Sleeper("Sleepy1", 1500), sleepy2 = new Sleeper("Sleepy2", 1500); Joiner joinsleepy1 = new Joiner("Join1", sleepy1), joinsleepy2 = new Joiner("Join2", sleepy2); sleepy1.interrupt(); } } |
五、总结:发现线程只要是在.start()状态,总有机会进入Cpu,就算标志中断了,也会去cpu执行对应的异常代码。