使用带锁的条件实例

时间:2015-05-17 19:13:55

标签: java multithreading concurrency locking

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

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

一个例子是有界缓冲类,例如here

因此,例如,当调用方法notFull.await()和notFull.signal()时,等待释放的内容/正在向其他线程发出信号的内容现在可以自由使用。

我的假设是,在这种情况下,这些方法正在检查/发信号通知锁的状态,无论是锁定还是解锁。 因此,例如,如果刚刚调用了lock.lock(),然后调用了notFull.await(),则会导致调用notFull.await()方法的线程被阻塞/发送到等待队列中。

我的结论是对的吗?

3 个答案:

答案 0 :(得分:0)

来自documentation

  

与此Condition关联的锁是原子释放的   当前线程因线程调度而被禁用   在四件事之一发生之前​​,它处于休眠状态:

     
      
  • 其他一些线程调用此Condition 的信号方法,当前线程恰好被选为要被唤醒的线程;   或
  •   
  • 其他一些帖子为此signalAll调用Condition方法;或
  •   
  • 其他一些线程中断当前线程,并支持线程挂起中断;或
  •   
  • A"虚假的唤醒"发生。
  •   

所以需要调用

notFull.signal();

notFull.signalAll();

或中断等待线程,或者需要进行虚假唤醒才能使等待线程再次运行。

答案 1 :(得分:0)

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

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

答案 2 :(得分:-1)

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


    }


}