java中的条件变量是什么?

2023-11-22

Q1.Java 中的 condVar 是什么?如果我看到下面的代码,条件变量是否必须位于 '互斥体.acquire()' and '互斥体.release()' block?

public void put(Object x) throws InterruptedException {
   mutex.acquire();
   try {
      while (count == array.length)
      notFull.await();
      array[putPtr] = x;
      putPtr = (putPtr + 1) % array.length;
      ++count;
      notEmpty.signal();
  }
  finally {
     mutex.release();
  }
}

我有三个线程我的线程A, 我的线程B, 我的线程C运行它调用相同的函数共同活动()触发该功能我的工作报告() e.g.

public void myWorkReport(){
    mutexMyWork.acquire();
    try{
         while(runMyWork){
             doWork();
             conditionMyWork.timedwait(sleepMyWork);
         }
    }
    finally{
       mutexMyWork.release()
    }    
}

public void commonActivity(){
    try{
        conditionMyWork.signal(); 
    }finally{
        //cleanup
    }   
}

public void myThreadA(){
    mutexA.acquire();
    try{
        while(runningA){    //runningA is a boolean variable, this is always true as long as application is running
            conditionA.timedwait(sleepA);
            commonActivity();
        }
    }
    finally{
        mutexA.release();
    }
}


public void myThreadB(){
    mutexB.acquire();
    try{
        while(runningB){    //runningB is a boolean variable, this is always true as long as application is running
            conditionB.timedwait(sleepB);
            commonActivity();
        }
    }
    finally{
        mutexB.release();
    }
}

public void myThreadC(){
    mutexC.acquire();
    try{
        while(runningC){    //runningC is a boolean variable, this is always true as long as application is running.
            conditionC.timedwait(sleepC);
            commonActivity();
        }
    }
    finally{
        mutexC.release();
    }
}

Q2.使用 timedwait 是一个很好的做法。我可以通过使用 sleep() 来实现相同的目的。如果使用 sleep() 调用不好,为什么?

Q3.有没有更好的方法来完成上述事情?

Q4.是否必须拥有条件.signal()对于每一个条件.timedwait(时间);


Q1)最好的资源可能是JavaDoc对于条件类。条件变量是一种机制,允许您在允许方法继续之前测试特定条件是否成立。在您的示例中,有两个条件,notFull and notEmpty.

您的示例中显示的 put 方法等待notFull在尝试将元素添加到数组之前,条件变为 true,并且一旦插入完成,它就会发出信号notEmpty唤醒任何阻塞等待从数组中删除元素的线程的条件。

...条件变量是否必然存在 必须在 'mutex.acquire()' 和 “mutex.release()”块?

任何更改条件变量的调用都需要在同步区域内 - 这可以通过内置的synchronized关键字或提供的同步器类之一java.util.concurrent包如Lock。如果您没有同步条件变量,则可能会出现两种负面结果:

  1. 丢失信号 - 这是一个线程检查条件并发现它不成立的情况,但在阻止另一个线程进入之前,执行一些操作以使条件变为真,然后向所有等待该条件的线程发出信号。不幸的是,第一个线程已经检查了条件,并且无论如何都会阻塞,即使它实际上可以继续。

  2. 第二个问题是常见问题,您可以有多个线程尝试同时修改共享状态。在您的示例中,多个线程可能会调用put()同时,所有这些人都检查条件并发现数组未满,并尝试插入数组,从而覆盖数组中的元素。

Q2)定时等待对于调试目的非常有用,因为它们允许您在线程未通过信号唤醒的情况下记录信息。

Using sleep()代替定时等待并不是一个好主意,因为如上所述,您需要调用await()同步区域内的方法,以及sleep()不释放任何持有的锁,同时await()做。这意味着任何休眠线程仍将持有它们已获取的锁,从而导致其他线程不必要地阻塞。

Q4)从技术上讲,不,你不需要打电话signal()但是,如果您使用定时等待,则意味着所有等待都不会返回,直到超时结束,这至少可以说是低效的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java中的条件变量是什么? 的相关文章

随机推荐