转换wait&notifyAll代码以使用Java 1.5 Lock对象

我们使用在代码段周围使用同步块的代码,需要大量的wait和notifyAll()调用。 我们正在尝试将这些转换为使用Java 5 Lock.lock()和Lock.unlock()方法。 如何迁移此代码以删除所有wait和notifyAll调用。 我不知道使用新的锁定function相当于这些。

任何与示例的链接将不胜感激。

提前致谢

方程式,下面的代码需要转换为使用Lock.lock()和lock.unlock删除synchronized块的第一部分很简单,因为我只需要调用lock()方法。 问题是可以为notifyAll()和wait方法做些什么。

     同步(LOCK)
             {
                 while(!Thread.interrupted())
                 {
                 尝试
                     {

                         working = runRules();

                        如果(!工作)
                             LOCK.notifyAll();

                         LOCK.wait(工作?shortTimeout:longTimeout);
                     }
                     catch(最终InterruptedException e)
                     {
                         Package.log.info(“线程被中断。退出。”,e);
                        返回;
                     }
                 }
             }

使用java.util.concurrent.locks包提供的Condition

  final Object monitor = ... ... synchronized (monitor) { while (!condition) monitor.wait(); ... do something ... } 

变为:

  final ReentrantLock lock = ...; final Condition cvar = lock.newCondition(); ... lock.lock(); try { while (!condition) cvar.await(); ... do something ... } finally { lock.unlock(); } 

信号方面非常相似:

  synchronized (monitor) { ... do something ... monitor.notify(); } 

变为:

  lock.lock(); try { ... do something ... cvar.signalAll(); } finally { lock.unlock(); } 

使用Lock.newCondition()工厂方法提供的Condition对象。 对象监视器的等待和通知方面已被考虑到此接口中。

从迁移的角度来看:

  • wait() – > await()
  • wait(long) – > await(long, TimeUnit.Millis)awaitNanos(long * 10000000)
  • notify() – > signal()
  • notifyAll() – > signalAll()

但是,条件在几个方面比监视器更强大。 首先,它们更精细,因此您可以为不同的事物提供多种条件。 例如,如果我有一个有界阻塞集合,我可以有一个条件为满和条件为空,并等待并在添加或删除元素时单独通知它们。

还有一些额外的await变体允许您等待而不会被中断并等待直到某个特定日期(时间)。

Condition类的javadoc非常好,并且非常详细地描述它和它的用法。

由于这个问题是关于notifyAll,我尝试了一些生产者/消费者与移相器的例子。 我没有使用过Lock,因为那需要try / finally,条件对象,直到解锁其他线程都行不通……等等……

 import java.util.concurrent.Phaser; public class ProducerConsumerExample { Phaser producer; Phaser consumers; volatile String array[]; public void init() { producer = new Phaser(5); consumers = new Phaser(5); Consumer l1 = new Consumer("Consumer_1"); l1.setDaemon(true); l1.start(); Consumer l2 = new Consumer("Consumer_2"); l2.setDaemon(true); l2.start(); Consumer l3 = new Consumer("Consumer_3"); l3.setDaemon(true); l3.start(); Consumer l4 = new Consumer("Consumer_4"); l4.setDaemon(true); l4.start(); } class Consumer extends Thread { Consumer(String name) { super(name); } private void printMethod(String i) { System.out.println(Thread.currentThread().getName() + " " + i); } public void run() { while (true) { //make the consumers sleep till producer produces consumers.arriveAndAwaitAdvance(); for (int i = 0; i < array.length; i++) { printMethod(array[i]); } //alert the producer to start producer.arriveAndAwaitAdvance(); System.out.println(Thread.currentThread().getName() + " thread wakeup but will stuck with consumers.arriveAndAwaitAdvance!"); } } } public void run() { for (int j = 0; j < 3; j++) { array = new String[5]; for (int i = 0; i < array.length; i++) { array[i] = "Phase_" + (j + 1) + " Count_" + (i + 1); } System.out.println("Main thread pushed data."); //alert the consumers to start consumers.arriveAndAwaitAdvance(); //make the producer sleep till all the consumer consumes producer.arriveAndAwaitAdvance(); System.out.println("Main thread wakeup and will start pushing data..."); } } public static void main(String[] args) { ProducerConsumerExample sch = new ProducerConsumerExample(); sch.init(); sch.run(); System.out.println("Main thread completed, producing data."); } }