なぜwait()はループに置かなければならないのか

1348 ワード

  :https://blog.csdn.net/yiifaa/article/details/76341707

マルチスレッドのプログラミングの実践では、wait()の使用方法は以下の通りである.
synchronized (monitor) {
    //              
    while(!locked) {
        //      
        monitor.wait();
    }
    //           
}

なぜif判断を採用せずにwhile判断をしなければならないのでしょうか.次のようになります.
synchronized (monitor) {
    //              
    if(!locked) {
        //      
        monitor.wait();
    }
    //           
}

これは、if判定を用いると、スレッドがwaitから起動すると、他のビジネスロジックを処理するコードが直接実行されるためであるが、この場合、条件述語がビジネスロジックを処理する条件を満たしていないため、誤った結果が生じる可能性があり、次のように再判断する必要があるからである.
synchronized (monitor) {
    //              
    if(!locked) {
        //      
        monitor.wait();
        if(locked) {
            //           
        } else {
            //     monitor.wait(); 
        }
    }
}

ループは上記の書き方の簡略化であり,起動後に再びwhile条件判断に入り,条件述語が変化して業務論理を処理し続ける誤りを避ける.これはJDKコードにも多く応用されており、例えばArrayBlockingQueue
    public E take() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == 0)
                notEmpty.await();//  condition         
            return extract();
        } finally {
            lock.unlock();
        }
    }