线程通信
2019-04-25 19:59
106 查看
当线程在系统内运行时,线程调度具有一定的透明性,程序通常无法准确控制线程的轮换执行,但我们可以通过一些机制来保证线程的协调运行。
1、传统的线程通信
假设现在系统中有两个线程,这两个线程分别代表取钱者和存款者-----并且假设系统有一种特殊的要求,系统要求存款者和取钱者不断地重复存钱、取钱的动作,而且要求每当存款者将钱存入指定账户后,取钱者就立即取出这笔钱。
为了实现这种功能,可以借助于Object类提供的wait()、notify()和notifyAll()三个方法,这三个方法属于Object类。但这三个方法必须由同步监视器对象来调用。
- 对于使用synchronized修饰的同步方法,因为该类的默认实例就是同步监视器,所以可以在同步方法中直接调用这三个方法。
- 对于使用synchronized修饰的同步代码块,同步监视器是synchronized后括号里的对象,所以必须使用该对象调用这三个方法。
关于这三个方法的解释如下:
- wait(): 导致该线程等待,直到其他线程调用该同步监视器的notify()方法或notifyAll()方法来唤醒该线程。
- notify(): 唤醒在此时同步监视器上等待的单个线程。如果所有线程都在此同步监视器上等待,则会唤醒其中一个线程。选择是任意性的。
- notifyAll(): 唤醒在此同步监视器上等待的所有线程。只有当前线程放弃对该同步监视器的锁定后,才可以执行被唤醒的线程。
2、使用Condition控制线程通信
如果程序不使用synchronized关键字来保证同步,而是直接使用Lock对象来保持同步,则系统中不存在隐式的同步监视器,也就不能使用wait()、notify()、notifyAll()方法进行现场通信了。
当使用Lock对象来保证同步时,Java提供了一个Condition类来保持协调,使用Condition可以让那些已经得到Lock对象却无法继续执行的线程释放Lock对象。在这种情况下,Lock替代了同步方法或同步代码块,Condition替代了同步监视器的功能。
Condition实例被绑定在一个Lock对象上。要获得特定Lock实例的Condition实例,调用Lock对象的newCondition()方法即可。Condition类提供了以下三种方法。
- await(): 类似于隐式同步监视器上的wait()方法,导致当前线程等待,直到其他线程调用该Condition的signal()或signalAll()方法来唤醒该线程。
- signal():唤醒在此Lock对象上等待的单个线程。
- signalAll(): 唤醒在此Lock对象上等待的所有线程。
相关文章推荐
- Android(java)学习笔记70:同步中的死锁问题以及线程通信问题
- Linux的进程/线程通信方式总结(转)
- 进程间通信机制(管道、信号、共享内存/信号量/消息队列)、线程间通信机制(互斥锁、条件变量、posix匿名信号量)
- 进程和线程的区别、通信方式的区别
- RT-Thread 学习笔记(二)---线程创建及任务间通信之中断锁
- C++多线程--线程间通信与线程同步
- 关于线程之间的通信问题
- java多线程详解(6)-线程间的通信wait及notify方法
- iOS学习笔记-103.多线程02——线程状态、同步、通信
- java线程间的同步与通信
- 多个线程之间是如何进行通信的呢?
- Java 多线程(六)——进程间通信与线程间通信
- Java基础(高级)——多线程的理解和Synchronized实例,以及线程间通信,wait,notify等方法
- 线程间的通信
- Java 里如何实现线程间通信?
- 黑马程序员-day12多线程-线程间通信
- Unix/Linux IPC及线程间通信总结
- Java线程(九):Condition-线程通信更高效的方式
- 彻底明白Java的多线程-线程间的通信(二)
- 进程间 / 线程间通信方式小结