转换等待&通知所有代码使用Java 1.5 Lock对象

发布于 2024-11-05 01:34:41 字数 970 浏览 0 评论 0原文

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

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

感谢 Advance

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

     synchronized( LOCK )
            {
                while( !Thread.interrupted() )
                {
                 try
                    {

                        working = runRules();

                        if( !working )
                            LOCK.notifyAll();

                        LOCK.wait( working ? shortTimeout : longTimeout );
                    }
                    catch( final InterruptedException e )
                    {
                        Package.log.info( "Thread was interrupted.  Exiting.", e );
                        return;
                    }
                }
            }

We use code that uses syncronized blocks around segments of code with a lot of wait and notifyAll() calls. We are trying to convert these to use Java 5 Lock.lock() and Lock.unlock() methods. How do I migrate this code to remove all the wait and notifyAll calls. I do not know the equivalent to these using the new Locking features.

Any links with examples would be appreciated.

Thanks in Advance

Eq., the following code needs to be converted to use Lock.lock() and lock.unlock The first part to remove the synchronized block is simple as I just need to call lock() method. The question is what can be done for the notifyAll() and wait methods.

     synchronized( LOCK )
            {
                while( !Thread.interrupted() )
                {
                 try
                    {

                        working = runRules();

                        if( !working )
                            LOCK.notifyAll();

                        LOCK.wait( working ? shortTimeout : longTimeout );
                    }
                    catch( final InterruptedException e )
                    {
                        Package.log.info( "Thread was interrupted.  Exiting.", e );
                        return;
                    }
                }
            }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

北座城市 2024-11-12 01:34:41

使用 条件<由 java.util.concurrent.locks提供的 /code>:

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

Use the Conditions provided by the java.util.concurrent.locks package:

 final Object monitor = ...

 ...

 synchronized (monitor) {

     while (!condition) monitor.wait();
     ... do something ...
 }

becomes:

 final ReentrantLock lock = ...;
 final Condition cvar = lock.newCondition();

 ...

 lock.lock();

 try {

     while (!condition) cvar.await();
     ... do something ... 

 } finally {

     lock.unlock();
 }

The signalling side is pretty similar:

 synchronized (monitor) {

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

becomes:

 lock.lock();

 try {

     ... do something ...
     cvar.signalAll();

 } finally {

     lock.unlock();
 }
双手揣兜 2024-11-12 01:34:41

使用 条件 Lock.newCondition()工厂方法提供的对象。对象监视器的等待和通知方面被分解到该接口中。

从迁移的角度来看:

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

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

还有其他 await 变体,允许您在不被中断的情况下等待,并等待到某个特定日期(时间)。

Condition< 的 javadoc /code>类非常好,并且非常详细地描述了它及其使用。

Use Condition objects provided by the Lock.newCondition() factory method. The waiting and notification aspects of an Object's monitor were factored out into this interface.

From a migration point of view:

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

However, conditions are more powerful than monitors in several ways. Firstly they are more fine grained, so you can have multiple conditions for different things. If I have a bounded blocking collection for instance, I can have a condition for full and a condition for empty, and await and notify these separately as elements are added or removed.

There are also additional await variants that allow you to await without being interrupted and await until a certain specific date (time).

The javadocs of the Condition class are very good and describe it and its use in great detail.

以歌曲疗慰 2024-11-12 01:34:41

由于这个问题谈论的是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.");
    }
}

Since this question is talking about notifyAll, i have tried some example of producer/consumer with phaser. I didn't used Lock, since that needs try/finally, condition object, and till unlock other thread will not work... etc...

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.");
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文