并发编程中的线程间通信
线程通信的目标是使线程能够相互发送信号。另一方面,线程通信使线程能够等待来自其他线程的信号。
常用的线程通信方式有:
等待/通知等待
易失性内存共享
CountDownLatch并发工具
ReentrantLock 与 Condition 结合使用
Basic LockSupport 实现线程之间的阻塞和唤醒
方法一:使用 volatile 关键字
基于 volatile 关键字实现线程之间的相互通信,就是利用共享内存的思想,大致的意思就是多个线程同时监听一个变量。当这个变量发生变化时,线程就可以感知并执行相应的业务。这也是最简单的实现方式
运行结果为:
方法二:使用Object类的wait()和notify()方法
众所周知,Object类提供了线程间通信方法:wait()、notify()、notifyaAl(),它们是多线程通信的基础,而这种实现的思想自然也是inter - 线程通信。
注意:wait和notify必须与synchronized一起使用。 wait方法释放锁,notify方法不释放锁。
运行结果是
从打印结果截图中我们可以看到,线程A发出notify()唤醒通知后,线程B仍然在处理完自己线程的事务后开始执行。这也正好说明了notify()方法并没有释放锁,而wait()方法也没有释放锁。 ) 方法释放锁。
方法三:使用JUC工具类CountDownLatch
jdk1.5之后,java.util.concurrent包下提供了很多与并发编程相关的工具类,简化了我们并发编程代码的编写。 ***CountDownLatch***是基于AQS框架的,相当于维护了一个线程。共享变量状态
运行结果为:
方法四:ReentrantLock结合Condition使用
运行结果为:
显然这种方法不太好用,代码写起来比较复杂,而且线程B因为被A唤醒后还没有获取到锁而无法立即执行。也就是说A被唤醒后并没有释放锁手术。该方法与Object的wait()和notify()相同。
方法五:Basic LockSupport实现线程间的阻塞和唤醒LockSupport是一个非常灵活的工具,用于实现线程之间的阻塞和唤醒。使用时,不必担心等待线程先运行还是唤醒线程先运行,但需要知道线程的名称。
运算结果