java 条件变量_关于JAVA Condition 条件变量

Condition 条件变量

条件变量是线程同步对象中的一种,主要用来等待某种条件的发生,条件发生后,可以唤醒等待在该条件上的一个线程,或所有线程。条件变量要与锁一起协同工作.

条件变量调用Lock.newCondition()获得一个实例:

ReentrantLock lock = new ReentrantLock();

Condition condition =

lock.newCondition();

通常的调用方式如下:

// 当条件 con == true 时等待

lock.lock();

try {

if (con == true) {

condition.await();

}

// do something

} finally {

lock.unlock();

}

// 条件变量的唤醒:

condition.signal(); //唤醒等待的其中一个线程

condition.signalAll(); //唤醒等待的所有线程

条件变量类似JDK1.4或以前版本中的 Object.wait(); Object.notify(); Object.notifyAll();

值得注意的是当condition.await()时,隐式的将条件变量关联的Lock解锁,而使其他线程有机会获得Lock,而检查条件,并在条件满足时,等待在条件变量上。

我们先来看一下没有条件变量时,传统的处理方式:

下面这个例子,创建3个等候线程,每个线程循环调用event.wait(),

等到了event后,显示相应的信息。

然后创建1个通知线程,每隔1秒调用 event.notify() 通知等待线程。

import java.util.Calendar;

public class TestWait {

// 创建event Object,以使用它的wait(), notify()等方法

private Object event = null;

public TestWait() {

// 创建event

event = new Object();

}

public static void main(String[] args) {

TestWait tester = new TestWait();

tester.test();

}

public Object getEvent() {

return event;

}

public void test() {

// 启动3个等候线程

new Thread(new WaitThread(this)).start();

new Thread(new WaitThread(this)).start();

new Thread(new WaitThread(this)).start();

// 启动通知线程

new Thread(new NotifyThread(this)).start();

}

}

class WaitThread implements Runnable {

private TestWait tester = null;

public WaitThread(TestWait tester) {

this.tester = tester;

}

public void run() {

Calendar now = Calendar.getInstance();

System.out.println(now.getTime() + " W " + Thread.currentThread() + " wait for event.");

while (true) {

try {

// 同步访问 event

synchronized (tester.getEvent()) {

// 等待在 event 上

tester.getEvent().wait();

}

// 等到 event 后,显示信息 "got event"

Calendar now1 = Calendar.getInstance();

System.out.println(now1.getTime() + " W " + Thread.currentThread() + " got event.");

// do something ...

Thread.sleep(500);

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

class NotifyThread implements Runnable {

private TestWait tester = null;

public NotifyThread(TestWait tester) {

this.tester = tester;

}

public void run() {

while (true) {

try {

// 间隔1秒

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

// 同步访问 event

synchronized (tester.getEvent()) {

// 通知等在event上的一个线程

tester.getEvent().notify();

// 通知等在event上的所有线程

// tester.getEvent().notifyAll();

// 打印 "fire event" 信息。

Calendar now = Calendar.getInstance();

System.out.println(now.getTime() + " N " + Thread.currentThread() + " fire event.");

}

}

}

}

程序运行结果如下:

Tue Jan 24 14:42:31 CST 2006 W Thread[Thread-0,5,main] wait for

event.

Tue Jan 24 14:42:31 CST 2006 W Thread[Thread-2,5,main] wait for

event.

Tue Jan 24 14:42:31 CST 2006 W Thread[Thread-1,5,main] wait for

event.

Tue Jan 24 14:42:31 CST 2006 N Thread[Thread-3,5,main] fire event.

Tue Jan 24 14:42:31 CST 2006 W Thread[Thread-0,5,main] got event.

Tue

Jan 24 14:42:32 CST 2006 N Thread[Thread-3,5,main] fire event.

Tue Jan 24

14:42:32 CST 2006 W Thread[Thread-2,5,main] got event.

Tue Jan 24 14:42:33

CST 2006 N Thread[Thread-3,5,main] fire event.

Tue Jan 24 14:42:33 CST 2006

W Thread[Thread-1,5,main] got event.

Tue Jan 24 14:42:34 CST 2006 N

Thread[Thread-3,5,main] fire event.

Tue Jan 24 14:42:34 CST 2006 W

Thread[Thread-0,5,main] got event.

Tue Jan 24 14:42:36 CST 2006 N

Thread[Thread-3,5,main] fire event.

Tue Jan 24 14:42:36 CST 2006 W

Thread[Thread-2,5,main] got event.

前三行启动3个等候线程,线程阻塞在 event.wait()上。

第四行通知线程Thread-3,调用event.notify();

第五行Thread-0线程,got event.

一秒钟后,Thread-3,又触发了event.notify();

下面将NotifyThread中的 event.notify();

改为event.notifyAll(); 看一下运行结果:

Tue Jan 24 15:25:43 CST 2006 W

Thread[Thread-1,5,main] wait for event.

Tue Jan 24 15:25:43 CST 2006 W

Thread[Thread-2,5,main] wait for event.

Tue Jan 24 15:25:43 CST 2006 W

Thread[Thread-0,5,main] wait for event.

Tue Jan 24 15:25:44 CST 2006 N

Thread[Thread-3,5,main] fire event.

Tue Jan 24 15:25:44 CST 2006 W

Thread[Thread-1,5,main] got event.

Tue Jan 24 15:25:44 CST 2006 W

Thread[Thread-0,5,main] got event.

Tue Jan 24 15:25:44 CST 2006 W

Thread[Thread-2,5,main] got event.

Tue Jan 24 15:25:45 CST 2006 N

Thread[Thread-3,5,main] fire event.

Tue Jan 24 15:25:45 CST 2006 W

Thread[Thread-0,5,main] got event.

Tue Jan 24 15:25:45 CST 2006 W

Thread[Thread-1,5,main] got event.

Tue Jan 24 15:25:45 CST 2006 W

Thread[Thread-2,5,main] got event.

Tue Jan 24 15:25:46 CST 2006 N

Thread[Thread-3,5,main] fire event.

Tue Jan 24 15:25:46 CST 2006 W

Thread[Thread-1,5,main] got event.

Tue Jan 24 15:25:46 CST 2006 W

Thread[Thread-0,5,main] got event.

Tue Jan 24 15:25:46 CST 2006 W

Thread[Thread-2,5,main] got event.

可以看到当Thread-3,event.notifyAll(); 所有的线程都

got event.

接下来,我们将这个例子改写为使用条件变量的例子:

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.ReentrantLock;

public class TestCondition {

private ReentrantLock lock = null;

private Condition condition = null;

public TestCondition() {

lock = new ReentrantLock();

condition = lock.newCondition();

}

public static void main(String[] args) {

TestCondition tester = new TestCondition();

tester.test();

}

public void test() {

new Thread(new WaitThread1(this)).start();

new Thread(new WaitThread1(this)).start();

new Thread(new WaitThread1(this)).start();

new Thread(new NotifyThread1(this)).start();

}

public ReentrantLock getLock() {

return lock;

}

public Condition getCondition() {

return condition;

}

}

class NotifyThread1 implements Runnable {

private TestCondition tester = null;

public NotifyThread1(TestCondition tester) {

this.tester = tester;

}

public void run() {

while (true) {

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

tester.getLock().lock();

tester.getCondition().signal();

System.out.println(Thread.currentThread() + " condition signal.");

tester.getLock().unlock();

}

}

}

class WaitThread1 implements Runnable {

private TestCondition tester = null;

public WaitThread1(TestCondition tester) {

this.tester = tester;

}

public void run() {

System.out.println(Thread.currentThread() + " started.");

while (true) {

tester.getLock().lock();

try {

// getCondition().await() 将使getLock()解锁,以便其他线程可以进入 await();

tester.getCondition().await();

System.out.println(Thread.currentThread() + " get condition.");

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

tester.getLock().unlock();

}

}

}

} 运行结果如下:

Thread[Thread-0,5,main] started.

Thread[Thread-1,5,main] started.

Thread[Thread-2,5,main] started.

Thread[Thread-3,5,main] condition

signal.

Thread[Thread-0,5,main] get condition.

Thread[Thread-3,5,main]

condition signal.

Thread[Thread-1,5,main] get condition.

Thread[Thread-3,5,main] condition signal.

Thread[Thread-2,5,main] get

condition.

Thread[Thread-3,5,main] condition signal.

Thread[Thread-0,5,main] get condition.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值