JAVA 并发编程-传统线程同步通信技术(四)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了JAVA 并发编程-传统线程同步通信技术(四),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2652字,纯文字阅读大概需要4分钟。
内容图文
首先介绍几个概念:
wait()方法
wait()方法使得当前线程必须要等待,等到另外一个线程调用notify()或者notifyAll()方法。
当前的线程必须拥有当前对象的monitor,也即lock,就是锁。
线程调用wait()方法,释放它对锁的拥有权,然后等待另外的线程来通知它(通知的方式是notify()或者notifyAll()方法),这样它才能重新获得锁的拥有权和恢复执行。
要确保调用wait()方法的时候拥有锁,即,wait()方法的调用必须放在synchronized方法或synchronized块中。
与sleep比较:
当线程调用了wait()方法时,它会释放掉对象的锁。
另一个会导致线程暂停的方法:Thread.sleep(),它会导致线程睡眠指定的毫秒数,但线程在睡眠的过程中是不会释放掉对象的锁的。
notify()方法
notify()方法会唤醒一个等待当前对象的锁的线程。
如果多个线程在等待,它们中的一个将会选择被唤醒。这种选择是随意的,和具体实现有关。(线程等待一个对象的锁是由于调用了wait方法中的一个)。
被唤醒的线程是不能被执行的,需要等到当前线程放弃这个对象的锁。
被唤醒的线程将和其他线程以通常的方式进行竞争,来获得对象的锁。也就是说,被唤醒的线程并没有什么优先权,也没有什么劣势,对象的下一个线程还是需要通过一般性的竞争。
notify()方法应该是被拥有对象的锁的线程所调用。
换句话说,和wait()方法一样,notify方法调用必须放在synchronized方法或synchronized块中。
wait()和notify()方法要求在调用时线程已经获得了对象的锁,因此对这两个方法的调用需要放在synchronized方法或synchronized块中。
线程同步通信实现demo:
传统线程同步通信技术,子线程循环10次,接着主线程循环100次,又回到子线程循环10次,接着再回到主线程又循环100次,如此循环50次
public class TraditionalThreadCommunication { /** * @param args */ public static void main(String[] args) { final Business business = new Business(); //创建了一个线程,并启动 new Thread( new Runnable() { @Override public void run() { for(int i=1;i<=50;i++){ //business的子函数 business.sub(i); } } } ).start(); //因为mian方法本身就占用一个线程,所以主线程不需要再new Thread for(int i=1;i<=50;i++){ business.main(i); } } } class Business { private boolean bShouldSub = true; //互斥对象为business,即在同一时刻只能访问sub或main其中一个方法 public synchronized void sub(int i){ //当bShouldSub==false时等待 while(!bShouldSub){ try { //方法使当前线程主动释放互斥锁,并进入该互斥锁的等待队列。(也就是说,它使当前线程暂停执行, //等待其他线程执行notify()方法或者notifyall()方法后再继续执行本线程。) this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } for(int j=1;j<=10;j++){ System.out.println("sub thread sequence of " + j + ",loop of " + i); } bShouldSub = false; //this代表什么?--代表Business //唤醒下一个线程 //唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。 //选择是任意性的,并在对实现做出决定时发生。 this.notify(); } public synchronized void main(int i){ //当bShouldSub==true时等待 while(bShouldSub){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } for(int j=1;j<=100;j++){ System.out.println("main thread sequence of " + j + ",loop of " + i); } bShouldSub = true; this.notify(); } }
打印结果 :
总结:
wait()和notify()方法要求在调用时线程已经获得了对象的锁,因此对这两个方法的调用需要放在synchronized方法或synchronized块中。synchronized保证了 main 和 sub 两个方法在同一时刻只能有一个在执行,那么bShouldSub值就是在判断该哪个方法执行。
执行过程可能为: sub() 方法先执行(当然也可能是 main 方法先执行,只是bShouldSub ==true ,则会的 wait ),bShouldSub ==true ,执行 for 循环,之后设置bShouldSub =false ,并唤醒等待线程,这时可能还是执行 sub() 方法(被唤醒的线程并没有什么优先权,也没有什么劣势,对象的下一个线程还是需要通过一般性的竞争) , 但此时bShouldSub ==false ,故执行 while 语句, wait ,然后 main () 方法执行。
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文:http://blog.csdn.net/hejingyuan6/article/details/46992453
内容总结
以上是互联网集市为您收集整理的JAVA 并发编程-传统线程同步通信技术(四)全部内容,希望文章能够帮你解决JAVA 并发编程-传统线程同步通信技术(四)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。