当前位置: 首页 > 面试题库 >

什么是Java中的条件变量?

闾丘博
2023-03-14
问题内容

Q1。 Java中的condVar是什么?如果我看到下面的代码,条件变量是否一定必须在“ mutex.acquire() ”和“
mutex.release() ”块内?

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();
  }
}

我有三个正在运行的线程 myThreadAmyThreadBmyThreadC ,它们调用相同的函数
commonActivity() 来触发函数 myWorkReport(), 例如

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。 每个 condition.timedwait(time); 是否必须具有 condition.signal( )?


问题答案:

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

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

…条件变量是否一定必须在’mutex.acquire()和’mutex.release()’块内?

任何更改条件变量的调用都必须在同步区域内-
这可以通过内置synchronized关键字或java.util.concurrent包提供的同步器类之一(例如Lock)进行。如果您不同步条件变量,则可能有两个负面结果:

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

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

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

使用sleep()代替定时的等待是不是一个好主意,因为上面提到你需要调用await()
一个同步的区域内的方法,并sleep()不会释放任何持有的锁,而await()做。这意味着任何睡眠线程仍将保持其已获取的锁,从而导致其他线程不必要地阻塞。

Q4)
从技术上讲,signal()如果您使用的是定时等待,则不需要呼叫,但是,这样做意味着直到超时过去,所有等待都不会返回,这至少可以说是无效的。



 类似资料:
  • 问题内容: 我正在读一本书,遇到过Java中的“影子变量”一词,但没有描述。最终,这些变量是做什么用的,以及如何实现? 问题答案: 除了提供我自己的描述之外,我可能会要求您例如在以下位置阅读它:http : //en.wikipedia.org/wiki/Variable_shadowing。了解变量的阴影后,建议您继续阅读有关覆盖/阴影方法和可见性的一般知识,以全面了解此类术语。 实际上,由于该

  • 问题内容: 这可能是有史以来最愚蠢的问题,但我认为对于Java新手来说,这非常令人困惑。 有人可以澄清什么是不变的吗? 为什么是String一成不变的? 不可变对象的优点/缺点是什么? 为什么诸如StringBuilderString之类的可变对象优先于String,反之亦然? 一个很好的例子(在Java中)将不胜感激。 问题答案: 不可变是指一旦对象的构造函数完成执行,该实例将无法更改。 这很有

  • 问题内容: 我搜索了该主题,但是除了Wikipedia之外,我没有找到任何其他有用的文档或文章。 有人可以用简单的词向我解释这意味着什么,还是可以使我参考一些易于理解的好文档? 问题答案: 对于Java而言,这并不意味着什么。 类不变式只是一个属性,它始终为一个类的所有实例保存,无论其他代码做什么。 例如, X具有不变的类,即存在一个属性,并且永远不存在,并且它具有type值。 无法保持两个重要的

  • 本文向大家介绍JavaScript中的条件运算符是什么?,包括了JavaScript中的条件运算符是什么?的使用技巧和注意事项,需要的朋友参考一下 条件运算符首先对表达式的真值或假值求值,然后根据求值结果执行两个给定语句之一。 序号 运算符和说明 1 ?:(视情况而定) 如果条件为真?然后取值X:否则取值Y 示例 尝试以下代码以了解条件运算符在JavaScript中的工作方式:

  • 问题内容: 我的任务是制作一个带有实例变量的程序,该变量应该由用户输入。但是我什至不知道什么是实例变量。什么是实例变量?如何创建一个?它有什么作用? 问题答案: 实例变量是在类内部但在方法外部声明的变量: 现在可以在其他类中实例化此IronMan类以使用这些变量,例如: 这就是我们使用实例变量的方式。无耻插头:来自实例本免费的电子书拉到这里这里。

  • 问题内容: 我正在阅读我的Deitel《 Java How to Program》一书,并遇到了“ 阴影 ”一词。如果允许阴影,那么Java类中有什么情况或目的? 例: 问题答案: 阴影的基本目的是使本地代码与周围的类分离。如果不可用,请考虑以下情况。 API中的Class Foo已发布。在代码中将其子类化,并在子类中使用名为bar的变量。然后,Foo发布更新,并在其类中添加一个称为Bar的受保护