「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战」。
并发编程中,我们需要处理两个关键问题:线程之间如何通信及线程之间如何同步。线程同步问题一般就是通过加锁解决,那你们知道线程间是如何通信的吗?本篇文章我们一起看一下Java中线程间是如何进行通信协作。
什么是线程之间的通信协作
首先,我们先理解通信的概念,我们每天都在使用的HTTP协议就是一种通信规则,我们可以通过客户端向服务端发起请求,将客户端的信息携带到服务端,并且获取到服务端的信息,所以通信的本质就是信息交换。
那我们如何完成不同线程之间的信息交换呢?共享变量,消息通知等等。
通信的目的是为了更好的协作,线程无论是交替式执行,还是接力式执行,都需要进行通信告知。
举个例子:共享变量的通信就像是老师在通过黑板向同学们讲课,老师将知识点写到黑板,同学们就能接收到这些知识点。
如何进行线程间的通信协作
线程之间的通信协作机制有如下几种:
-
共享变量
需要注意的是,Java内存模型(JMM)采用的是共享内存模型,Java线程之间的通信总是隐式进行,整个通信过程对程序员完全透明。如果编写多线程程序的Java程序员不理解隐式进行的线程之间通信的工作机制,很可能会遇到各种奇怪的内存可见性问题。
这时volatile关键字就可以派上用场,他修饰的共享变量,具有两大特性可见性、有序性,能够有效禁止指令重排序,其中可见性就是可以让线程之间进行通信。
-
管道方式,主要用来实现两个线程之间的二进制数据的传播
- 字节流
- 字符流
-
等待通知机制都是锁级别
- syncrhoized关键字加锁的线程的Object类的wait()/notify()/notifyAll()
- ReentrantLock类加锁的线程的Condition类的await()/signal()/signalAll()
-
join 方式
join 就是当一个线程调用另一个线程的join方法时,当前线程阻塞等待被调用join方法的线程执行完毕才能继续执行,所以join的好处能够保证线程的执行顺序,但是如果调用线程的join方法其实已经失去了并行的意义,虽然存在多个线程,但是本质上还是串行的,最后join的实现其实是基于等待通知机制的。