谈谈你对Java线程之间通信方式的理解
线程之间通信的方式:
- ① 同步
- ② while轮询的方式
- ③ wait/notify机制
- ④ 管道通信
同步
多个线程通过synchronized关键字持有同一个对象实现线程间的通信。本质上就是“共享内存”式的通信。多个线程需要访问同一个共享变量,谁拿到了锁(获得了访问权限),谁就可以执行。
while轮询的方式
多个线程共享一个变量实现线程间的通信。
缺点是某一个线程需要不断while循环测试条件是否成立,不仅浪费了CPU资源,轮询的条件还会有可见性问题。
线程都是先把变量读取到本地线程栈空间,然后再去修改的本地变量。因此,如果线程每次都在取本地的条件变量,那么尽管另外一个线程已经改变了轮询的条件,它也察觉不到,这样也会造成死循环。
wait/notify机制
使用到了Object类的 wait() 和 notify() 方法,两个方法都需要配合synchronized关键字使用,它们的调用必须先获取到锁。
线程A调用wait() 放弃CPU,并进入阻塞状态。
线程B调用notify()通知线程A。
这种方式的一个好处就是CPU的利用率提高了。
但是也有一些缺点:比如,线程B先执行,一下子添加了5个元素并调用了notify()发送了通知,而此时线程A才执行;当线程A执行并调用wait()时,那它永远就不可能被唤醒了。因为,线程B已经发了通知了,以后不再发通知了。这说明:通知过早,会打乱程序的执行逻辑。
管道通信
就是使用java.io.PipedInputStream 和 java.io.PipedOutputStream进行通信
总结
分布式系统中说的两种通信机制:共享内存机制和消息通信机制。感觉前面的①中的synchronized关键字和②中的while轮询 “属于” 共享内存机制,由于是轮询的条件使用了volatile关键字修饰时,这就表示它们通过判断这个“共享的条件变量“是否改变了,来实现进程间的交流。
而管道通信,更像消息传递机制,也就是说:通过管道,将一个线程中的消息发送给另一个。
参考: |