通信方式
- ①同步
- ②while轮询的方式
- ③wait/notify机制
- ④管道通信
- 多个线程通过synchronized关键字这种方式来实现线程间的通信。
- 本质上就是“共享内存”式的通信。多个线程需要访问同一个共享变量,谁拿到了锁(获得了访问权限),谁就可以执行。
线程A和线程B持有同一个MyObject类的对象object,尽管这两个线程需要调用不同的方法,但是它们是同步执行的,比如:线程B需要等待线程A执行完了methodA()方法之后,它才能执行methodB()方法。这样,线程A和线程B就实现了 通信。
- 线程A不断地改变条件,线程ThreadB不停地通过while语句检测while中的条件是否成立 ,从而实现了线程间的通信。
- 1. 会浪费CPU资源。因为JVM调度器将CPU交给线程B执行时,它一直在轮询。
- 2. 轮询的条件的可见性问题:线程都是先把变量读取到本地线程栈空间,然后再去再去修改的本地变量。因此,如果线程B每次都在取本地的 条件变量,那么尽管另外一个线程已经改变了轮询的条件,它也察觉不到,这样也会造成死循环。
- 通过Object类的 wait() 和 notify() 方法完成两个线程间的通信。
- 当条件未满足时,线程A调用wait() 放弃CPU,并进入阻塞状态。
- 当条件满足时,线程B调用 notify()通知 线程A,所谓通知线程A,就是唤醒线程A,并让它进入可运行状态。
- CPU的利用率提高了。
- 如果通知过早,会打乱程序的执行逻辑。
- 比如,线程B先执行,一下子添加了5个元素并调用了notify()发送了通知,
- 而此时线程A还执行;
- 当线程A执行并调用wait()时,那它永远就不可能被唤醒了。
- 因为,线程B已经发了通知了,以后不再发通知了。这
- 使用java.io.PipedInputStream 和 java.io.PipedOutputStream进行通信
- ①中的synchronized关键字和②中的while轮询 “属于” 共享内存机制
- 由于是轮询的条件使用了volatile关键字修饰时,这就表示它们通过判断这个“共享的条件变量“是否改变了,来实现进程间的交流。
管道通信,更像消息传递机制:通过管道,将一个线程中的消息发送给另一个。