为什么需要线程通信
节约资源。
- 线程是操作系统调度的最小单位,拥有自己的栈空间
- 如果线程间都孤立地运行,就会造成资源浪费
- 所以线程之间需要相互协作,这个过程就是线程通信
线程通信的方式
1.共享内存
- 线程之间共享程序的公共状态,线程之间通过读写内存中的公共状态来隐式通信。
- volatile共享内存
2.消息传递
- 线程之间没有公共的状态,线程之间必须通过明确的发送信息来显示的进行通信。
- wait / notify
- join
3.管道流
- 管道输入/输出流的形式
共享内存
- 对线程来说,一些局部变量、方法定义的参数存放在本地内存
- 可供线程之间共享的如:堆内存的数据(实例域、静态域和数组元素),被存放在主内存
- 线程的本地内存中有共享变量的副本
volatile关键字:保证内存可见性,当某一个线程修改完变量后,需要将最新修改的值写回到主内存。
消息传递
1.wait/notify等待通知方式
- 处于等待状态的线程被由其他线程发出的通知唤醒后,重新争取CPU资源
- 生产者-消费者模式
等待方:
synchronized(对象){
while(条件不满足){
对象.wait()
}
对应的处理逻辑
}
通知方:
synchronized(对象){
改变条件
对象.notifyAll
}
2.join方式
join()方法的作用是:在当前线程A调用线程B的join()方法后,会让当前线程A阻塞,直到线程B的逻辑执行完成,A线程才会解除阻塞,然后继续执行自己的业务逻辑,这样做可以节省计算机中资源。
管道输入/输出流
管道输入/输出流主要包括4种具体的实现:PipedOutputStrean、PipedInputStrean、PipedReader和PipedWriter,前两种面向字节,后两种面向字符。
对于Piped类型的流,必须先进性绑定,也就是调用connect()方法,如果没有将输入/输出流绑定起来,对于该流的访问将抛出异常。