600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > java多线程编程(六)-线程间通信

java多线程编程(六)-线程间通信

时间:2020-11-01 01:51:25

相关推荐

java多线程编程(六)-线程间通信

一:线程通信介绍

线程通信是通过主动放弃对资源的使用,而让给其它线程的过程。合理的安排多个线程对同一资源的使用,即设计线程间的通信,可以完成很多复杂的任务。

二:线程通信实现

1,java.lang.Object超类

a,上图为Object类的常用方法,其中提供的notify(),notifyAll(),wait(),wait(long timeout) 和 wait(long timeout,int nanos)五个方法可以实现线程间通信。

b,五个方法都是被final修饰,所以不能被重写。

2,notify方法

notify()使用介绍:Wakes up a single thread that is waiting for this object's monitor.

notifyAll()使用介绍:Wakes up all threads that are waiting for this object's monitor.

3,wait方法

wait()使用介绍:Causes the current thread to wait until another thread invokes the notify() or the notifyAll() method for this object.

wait(long timeout)使用介绍:Causes the current thread to wait until either another thread invokes the notify() or notifyAll() method for this object,or a specified amount of time has elapsed.

wait(long timeout, int nanos)使用介绍:Causes the current thread to wait until another thread invokes the notify() or the notifyAll() method for this object,or some other thread interrupts the current thread ,or a centain amount of the real time has elapsed.

4,个人总结和附录

a,wait后的线程只能通过notify方法唤醒,从而重新进入就绪状态。

b,notify()方法只能唤醒一个在wait的线程,且是随机的。

c,从使用介绍中的 ‘current thread’,解读wait方法的使用需要使用线程必须拥有目标对象的锁,而notify()中使用介绍是主动唤醒其它线程,所以也必须拥有目标对象的锁才有资格去唤醒其它线程。所以wait()和notify方法的使用线程必须拥有目标对象的锁,即在使用时,wait方法和notify方法必须放在synchronized方法或sysnchronized代码块中。

d,wait方法是主动放弃锁,使线程进入等待锁,发生等待阻塞。而sleep方法并没有让线程放弃对象的锁。

附录

wake up:唤醒

monitor:监视器,即lock,锁。

causer:导致,引起

invokes:调用

specified time:指定的时间

elapsed:逝去的

三:设计案例(1010..案例)

1,基础案例

下述案利用合理设计线程间的通信例,实现了1010..的打印。

1 package com.thread.www; 2 /** 3 * 得到 1010的输出结果 4 * @author xiaojia 5 * 6 */ 7 //目标对象 8 class NumberHolder { 9private int num = 0;10//加数11public synchronized void increaseNum(){12 if(0 != num){13 try {14 wait();15 } catch (InterruptedException e) {16 e.printStackTrace();17 }18 }19 num ++;20 System.out.print(num);21 22 notify();23}24//减数25public synchronized void decreaseNum(){26 if(0 == num){27 try {28 wait();29 } catch (InterruptedException e) {30 e.printStackTrace();31 }32 }33 num --;34 System.out.print(num);35 notify();36}37 }38 39 //加数线程 和 减数线程40 class IncreaseThread extends Thread{41NumberHolder nholder;4243public IncreaseThread(NumberHolder nholder) {44 this.nholder = nholder;45}4647@Override48public void run() {49 50 for (int i = 0; i < 10; i++) {51 nholder.increaseNum();52 }53}54 }55 56 class DecreaseThread extends Thread{57NumberHolder nholder;5859public DecreaseThread(NumberHolder nholder) {60 this.nholder = nholder;61}6263@Override64public void run() {65 66 for (int i = 0; i < 10; i++) {67 nholder.decreaseNum();68 }69}70 }71 72 //启动线程73 public class Test7线程间的通信1 {74 75public static void main(String[] args) {76 NumberHolder nholder = new NumberHolder();77 78 IncreaseThread inTh = new IncreaseThread(nholder);79 DecreaseThread deTh = new DecreaseThread(nholder);80 81 inTh.start();82 deTh.start();83}84 85 }

basics Code

2,问题案例

如果创建多个线程,进行加数和减数,基础案例就得不到1010..有规律的打印了,main方法修改如下:

1 public class Test8线程间的通信2 { 2 3public static void main(String[] args) { 4 NumberHolder numHolder = new NumberHolder(); 56 IncreaseThread inTh = new IncreaseThread(numHolder); 7 DecreaseThread deTh = new DecreaseThread(numHolder); 8 inTh.start(); 9 deTh.start();10 11 IncreaseThread inTh2 = new IncreaseThread(numHolder);12 DecreaseThread deTh2 = new DecreaseThread(numHolder);13 inTh2.start();14 deTh2.start();15}16 }

3,完整案例

问题案例中,由于有四个创建的线程,拥有锁对象的线程唤醒wait的其它三个线程是随机的,因此不能按规律打印1010..。

解决办法:将加数和减数方法进入wait的if判断修改为while条件,这样当线程被唤醒后还是要进行进行零和非零的判断,才能加数或减数。

1 package com.thread.www; 2 3 class NumberHolder3 { 4private int num = 0; 5public synchronized void increaseNum(){ 6 while(num != 0){ 7 try { 8 wait(); 9 } catch (InterruptedException e) {10 e.printStackTrace();11 }12 }13 num ++;14 System.out.print(num+" ");15 16 notify();17}1819public synchronized void decreaseNum(){20 while(num == 0){21 try {22 wait();23 } catch (InterruptedException e) {24 e.printStackTrace();25 }26 }27 num --;28 System.out.print(num+" ");29 30 notify();31}32 }33 34 class IncreaseThread3 extends Thread{35private NumberHolder3 numHolder;36public IncreaseThread3(NumberHolder3 numHolder) {37 this.numHolder = numHolder;38}39@Override40public void run() {41 for (int i = 0; i < 10; i++) {42 try {43 sleep(1000);44 } catch (InterruptedException e) {45 e.printStackTrace();46 }47 numHolder.increaseNum();48 }49}50 }51 52 class DecreaseThread3 extends Thread{53private NumberHolder3 numHolder;54public DecreaseThread3(NumberHolder3 numHolder) {55 this.numHolder = numHolder;56}57@Override58public void run() {59 for (int i = 0; i < 10; i++) {60 try {61 sleep((long)Math.random()*1000);62 } catch (InterruptedException e) {63 e.printStackTrace();64 }65 numHolder.decreaseNum();66 }67}68 }69 70 public class Test9线程间的通信3 {71 72public static void main(String[] args) {73 NumberHolder3 numHolder = new NumberHolder3();74 75 IncreaseThread3 inTh = new IncreaseThread3(numHolder);76 DecreaseThread3 deTh = new DecreaseThread3(numHolder);77 inTh.start();78 deTh.start();79 80 IncreaseThread3 inTh3 = new IncreaseThread3(numHolder);81 DecreaseThread3 deTh3 = new DecreaseThread3(numHolder);82 inTh3.start();83 deTh3.start();84 85}86 87 }

complete code

参考资料:/javase/7/docs/api/java/lang/Object.html#notify()

/mengdd/archive//02/20/2917956.html

原文路径:/xiaojia-new/p/8604606.html

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。