当条件与这样的锁相关联时会发生什么:
Lock lock = new ReentrantLock();
Condition notFull = lock.newCondition();
一个例子是有界缓冲类,例如here
因此,例如,当调用方法notFull.await()和notFull.signal()时,等待释放的内容/正在向其他线程发出信号的内容现在可以自由使用。
我的假设是,在这种情况下,这些方法正在检查/发信号通知锁的状态,无论是锁定还是解锁。 因此,例如,如果刚刚调用了lock.lock(),然后调用了notFull.await(),则会导致调用notFull.await()方法的线程被阻塞/发送到等待队列中。
我的结论是对的吗?
答案 0 :(得分:0)
与此
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();
}
}