使用带锁的条件实例

Using a condition instance with a lock

当条件与这样的锁关联时会发生什么:

Lock lock = new ReentrantLock();
Condition notFull  = lock.newCondition();

一个例子是有界缓冲区 class 例如 here

因此,例如,当调用方法 notFull.await() 和 notFull.signal() 时,正在等待 released/what 的内容将作为信号通知其他线程现在可以免费使用了。

我的假设是,在这种情况下,这些方法是 checking/signaling 锁的状态,无论是锁定还是解锁。 因此,例如,如果 lock.lock() 刚刚被调用,然后 notFull.await() 被调用,这将导致调用 notFull.await() 方法的线程成为 blocked/sent等待队列。

我的结论正确吗?

来自documentation

The lock associated with this Condition is atomically released and the current thread becomes disabled for thread scheduling purposes and lies dormant until one of four things happens:

  • Some other thread invokes the signal method for this Condition and the current thread happens to be chosen as the thread to be awakened; or
  • Some other thread invokes the signalAll method for this Condition; or
  • Some other thread interrupts the current thread, and interruption of thread suspension is supported; or
  • A "spurious wakeup" occurs.

所以需要调用

notFull.signal();

notFull.signalAll();

或中断正在等待的线程,否则需要进行虚假唤醒才能使正在等待的线程再次运行。

您的示例看起来像是有界阻塞队列(或其他有界阻塞池类 class)实现的一部分。通过添加项目将队列状态从非空更改为空的生产者将调用 notEmpty.notify(),以便在 notEmpty.await() 调用中等待的消费者可以唤醒并从队列中删除新项目排队。

同样,通过删除项目将状态从已满更改为未满的消费者将调用 notFull.notify() 来唤醒在 notFull.await() 调用中被阻止的生产者。

package com.testjava;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//=========== Task1 class prints odd =====
class TaskClass1 implements Runnable
{

    private Condition condition;
    private Lock lock;
    boolean exit = false;
    int i;
    TaskClass1(Condition condition,Lock lock)
    {
        this.condition = condition;
        this.lock = lock;
    }
    @Override
    public void run() {
        try
        {
            lock.lock();
            for(i = 1;i<11;i++)
            {
                if(i%2 == 0)
                {
                    condition.signal();
                    condition.await();

                }
                if(i%2 != 0)
                {
                    System.out.println(Thread.currentThread().getName()+" == "+i);

                }

            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally
        {
            lock.unlock();
        }

    }

}
//==== Task2 : prints even =======
class TaskClass2 implements Runnable
{

    private Condition condition;
    private Lock lock;
    boolean exit = false;
    TaskClass2(Condition condition,Lock lock)
    {
        this.condition = condition;
        this.lock = lock;
    }
    @Override
    public void run() {
        int i;
        // TODO Auto-generated method stub
        try
        {
            lock.lock();
            for(i = 2;i<11;i++)

            {

                if(i%2 != 0)
                {
                    condition.signal();
                    condition.await();
                }
                if(i%2 == 0)
                {
                    System.out.println(Thread.currentThread().getName()+" == "+i);

                }

            }

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally
        {
            lock.unlock();

        }

    }

}
public class OddEven {

    public static void main(String[] a)
    {
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        Future future1;
        Future future2;
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        future1 = executorService.submit(new TaskClass1(condition,lock));
        future2 = executorService.submit(new TaskClass2(condition,lock));
        executorService.shutdown();


    }


}