Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:等待布尔值变为真_Java_Multithreading - Fatal编程技术网

Java:等待布尔值变为真

Java:等待布尔值变为真,java,multithreading,Java,Multithreading,我实现了一个任务,当前线程将等待以前的工作完成 代码: 另一个线程将isPreviousWorkOne设置为true,然后我们可以运行doSomething()。但我认为我的代码不好: 我们检查每个100ms,它可能会占用一些CPU资源 很难添加等待超时。(如果ispreviousworkone永远不会成为真的会怎样?) 那么,如何正确地实现这样的等待呢?您试图实现的是监视器的工作。使用对象作为监视器,您可以在需要时让线程等待/唤醒 synchronized(lock) { while(

我实现了一个任务,当前线程将等待以前的工作完成

代码:

另一个线程将
isPreviousWorkOne
设置为true,然后我们可以运行
doSomething()
。但我认为我的代码不好:

  • 我们检查每个
    100ms
    ,它可能会占用一些CPU资源
  • 很难添加等待超时。(如果
    ispreviousworkone
    永远不会成为真的会怎样?)

  • 那么,如何正确地实现这样的等待呢?

    您试图实现的是监视器的工作。使用对象作为监视器,您可以在需要时让线程等待/唤醒

    synchronized(lock)
    {
        while(!taskContext.isPreviousWorkDone())
        {
            try
            {
                // Object lock has to be accessible both by waiting thread and any
                // other thread that marks the previous work as done
                lock.wait();
            }   
        }
    }
    
    现在,无论在哪里更新任务上下文,都必须唤醒等待的线程

    // Method where you update taskContext
    public synchronized void setWorkAsDone() throws Exception
    {
        // ...
        _isPreviousWorkDone = true;
        notifyAll();
        // ...
    }
    

    改用倒计时闩锁。允许一个或多个线程等待某些操作完成

    CountDownLatch是用给定的计数初始化的。需要等待某些条件/操作(使计数达到零)的线程调用wait()方法之一。通过调用countdown()方法,从完成某些操作的线程中递减计数。然后,所有等待的线程继续执行

    示例

    // create latch with count of one (1)
    CountDownLatch latch = new CountDownLatch(1);
    
    // create instances of classes that implement Runnable
    Waiter waiter = new Waiter(latch);
    Worker worker = new Worker(latch);
    
    // start threads
    new Thread(waiter).start();
    new Thread(worker).start();
    
    定义服务员可运行(等待某些操作完成)

    定义工作线程可运行(执行某些操作)

    避免

    使用旧的wait-notifyjavaapi。原因是虚假唤醒。也就是说,您的线程在没有收到实际通知的情况下被唤醒,因此您必须检查您的条件是否满足,或者继续等待

    来自的虚假唤醒

    线程也可以在不被通知、中断或超时的情况下唤醒,即所谓的虚假唤醒。虽然这种情况在实践中很少发生,但应用程序必须通过测试本应导致线程被唤醒的条件来防范这种情况,并在条件不满足时继续等待。换句话说,等待应该总是在循环中发生,如下所示:

     synchronized (obj) {
         while (<condition does not hold>)
             obj.wait(timeout);
         ... // Perform action appropriate to condition
     }
    
    synchronized(obj){
    而()
    对象等待(超时);
    …//执行适合条件的操作
    }
    

    (有关此主题的更多信息,请参阅Doug Lea的“Java并发编程(第二版)”(Addison Wesley,2000)中的第3.2.3节,或Joshua Bloch的“有效Java编程语言指南”(Addison Wesley,2001)中的第50项。

    您可以构建超时检查此问题:使用等待而不是睡眠,并使用信号:)您可以使用
    Object#wait
    ReentrantLock
    条件
    countdownlock
    CyclicBarrier
    ,如果这种等待只发生一次。对于重复发生的内容,请使用
    ExecutorService
    Future
    public class Waiter implements Runnable{
        CountDownLatch latch = null;
    
        public Waiter(CountDownLatch latch) {
            this.latch = latch;
        }
    
        public void run() {
            try {
                // wait for the latch to be released
                latch.await();
            } catch (InterruptedException e) {
                // set interupt flag
                Thread.currentThread().interrupt();
                // log interrupt
                System.out.println("Interrupted");
            }
            System.out.println("Unblocked");
    
            doSomething();
        }
    }
    
    public class Worker implements Runnable {
        CountDownLatch latch = null;
    
        public Worker(CountDownLatch latch) {
            this.latch = latch;
        }
    
        public void run() {
            // do some job
    
            // when ready release latch
            latch.countDown();
    
            System.out.println("Latch Released");
        }
    }
    
     synchronized (obj) {
         while (<condition does not hold>)
             obj.wait(timeout);
         ... // Perform action appropriate to condition
     }