博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Condition监视器实现精准唤醒,且不需要标识符
阅读量:98 次
发布时间:2019-02-26

本文共 2425 字,大约阅读时间需要 8 分钟。

参考了很多网上的资料和视频,发现Condition监视器的精准唤醒例子都需要使用标识符,但实际上使用标识符的话是可以不用到Condition监视器的直接用Object监视器(wait/notify)来执行的。

个人感觉这些例子举得都不好,所以自己写了不用标识符的情况下可以直接用Condition来实现精准唤醒的例子,也从中发现了一些问题,具体已经写在注释。

public class TestJUC05 {
public static void main(String[] args) throws InterruptedException {
Data data = new Data(); new Thread(()->{
for (int i = 0; i < 10; i++) {
data.B(); } },"BB").start(); new Thread(()->{
for (int i = 0; i < 10; i++) {
data.C(); } },"CC").start(); //让A线程最后最后执行才对下一个线程的condition监视器唤醒起效,才能进入一个循环, //否则一开始A线程执行得太快,有可能会导致当B线程的监视器还没等待的时候已经执行唤醒, //然后之后就全部线程都无法唤醒,进入死循环 Thread.sleep(1000); new Thread(()->{
for (int i = 0; i < 10; i++) {
data.A(); } },"AA").start(); }}class Data{
private Lock lock=new ReentrantLock(); Condition condition1=lock.newCondition(); Condition condition2=lock.newCondition(); Condition condition3=lock.newCondition(); //该标识符用于标识A线程是否第一次执行 int number=0; public void A(){
lock.lock(); try {
//第一次不用等待直接执行,之后的都需要等待线程C的唤醒 if (number!=0) {
condition1.await(); } System.out.println("AAAAAAAAAAAAAA"); number++; //让BC线程先跑都进入等待,才能对B线程进行唤醒 condition2.signalAll(); } catch (InterruptedException e) {
e.printStackTrace(); } finally {
lock.unlock(); } } public void B(){
lock.lock(); try {
condition2.await(); System.out.println("BBBBBBBBBBBBBBBB"); condition3.signalAll(); } catch (InterruptedException e) {
e.printStackTrace(); } finally {
lock.unlock(); } } public void C(){
lock.lock(); try {
condition3.await(); System.out.println("CCCCCCCCCCCCCCCC"); condition1.signalAll(); } catch (InterruptedException e) {
e.printStackTrace(); } finally {
lock.unlock(); } }}
//运行结果AAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCC......

转载地址:http://rhru.baihongyu.com/

你可能感兴趣的文章