Condition 是在 java1.5 才出现. 它用来替换传统的 wait(), notify() 实现线程之间的协作. 但是更加强大.
Condition 用 await(), signal, signalAll 方法替代 wait(), notify(). 假如用 wait,notify, 有三个线程调用一个对象的某个方法, notify 只能随机的唤醒一个线程, 而不能指定唤醒某个线程, 但是用 condition 的话, 就可以唤醒指定的线程. 可以看下面的例子.
condition 的 await,signal 和 wait,notify 都需要在锁之间运行.
contidion 也被用来实现阻塞队列.
condition 是通过锁创建出来的. 基本代码是 ReentrantLock.newCondition().
- lock.lock();
- condition.await();
- lock.unlock();
- View Code
下面实现一个 一直 abc abc 这么有顺序的执行.
下面用 synchronized , wait ,notify 来实现.
总共有四个类. DemoNoCondition, A,B,C. 其中 DemoNoCondition 内部有三个方法, a,b,c, 都加上了锁, 用来打印 abc 的. A B C 三个类, 用来表示多个线程调用 DemoNoCondition 的几个方法来打印 abc
- package com.citi.test.mutiplethread.demo5;
- public class DemoNoCondition {
- private int signal;
- public synchronized void a(){
- while(signal!=0){
- try {
- wait();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- System.out.println("a"+signal);
- signal++;
- notifyAll();
- }
- public synchronized void b(){
- while(signal!=1){
- try {
- wait();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- System.out.println("b"+signal);
- signal++;
- notifyAll();
- }
- public synchronized void c(){
- while(signal!=2){
- try {
- wait();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- System.out.println("c"+signal);
- signal=0;
- notifyAll();
- }
- public static void main(String[] args) {
- DemoNoCondition d=new DemoNoCondition();
- A a=new A(d);
- B b=new B(d);
- C c=new C(d);
- new Thread(a).start();
- new Thread(a).start();
- new Thread(a).start();
- new Thread(a).start();
- new Thread(c).start();
- new Thread(c).start();
- new Thread(c).start();
- new Thread(c).start();
- new Thread(b).start();
- new Thread(b).start();
- new Thread(b).start();
- new Thread(b).start();
- new Thread(b).start();
- }
- }
- package com.citi.test.mutiplethread.demo5;
- public class A implements Runnable{
- private DemoNoCondition demoCondition;
- public A(DemoNoCondition demo) {
- this.demoCondition=demo;
- }
- @Override
- public void run() {
- while(true){
- demoCondition.a();
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
- package com.citi.test.mutiplethread.demo5;
- public class B implements Runnable {
- private DemoNoCondition demoCondition;
- public B(DemoNoCondition demoCondition) {
- this.demoCondition=demoCondition;
- }
- @Override
- public void run() {
- while(true){
- demoCondition.b();
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
- package com.citi.test.mutiplethread.demo5;
- public class C implements Runnable {
- private DemoNoCondition demoCondition;
- public C(DemoNoCondition demoCondition) {
- this.demoCondition=demoCondition;
- }
- @Override
- public void run() {
- while(true){
- demoCondition.c();
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
下面是输出结果.
下面来看看用 condition 来实现这个功能. 代码其实是类似的, 只不过, 用 condition, 可以指定唤醒某个线程. 可以对比一下两个实现的代码, 一个是用 notifyAll, 一个是直接指定
c.signal, 来通知线程 c 唤醒. 这个就是 condition 的强大之处.
- package com.citi.test.mutiplethread.demo5;
- import java.util.concurrent.locks.Condition;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
- public class DemoCondition {
- private int signal;
- private Lock lock=new ReentrantLock();
- private Condition a=lock.newCondition();
- private Condition b=lock.newCondition();
- private Condition c=lock.newCondition();
- public void a(){
- lock.lock();
- while(signal!=0){
- try {
- a.await();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- System.out.println("a"+signal);
- signal++;
- b.signal();
- lock.unlock();
- }
- public void b(){
- lock.lock();
- while(signal!=1){
- try {
- b.await();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- System.out.println("b"+signal);
- signal++;
- c.signal();
- lock.unlock();
- }
- public void c(){
- lock.lock();
- while(signal!=2){
- try {
- c.await();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- System.out.println("c"+signal);
- signal=0;
- a.signal();
- lock.unlock();
- }
- public static void main(String[] args) {
- DemoCondition condition=new DemoCondition();
- ACondition a=new ACondition(condition);
- BCondition b=new BCondition(condition);
- CCondition c=new CCondition(condition);
- new Thread(b).start();
- new Thread(a).start();
- new Thread(a).start();
- new Thread(b).start();
- new Thread(c).start();
- new Thread(a).start();
- new Thread(c).start();
- new Thread(a).start();
- new Thread(c).start();
- new Thread(c).start();
- }
- }
- package com.citi.test.mutiplethread.demo5;
- public class ACondition implements Runnable {
- private DemoCondition condition;
- public ACondition(DemoCondition condition) {
- this.condition=condition;
- }
- @Override
- public void run() {
- while(true){
- condition.a();
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
- package com.citi.test.mutiplethread.demo5;
- public class BCondition implements Runnable {
- private DemoCondition condition;
- public BCondition(DemoCondition condition) {
- this.condition = condition;
- }
- public void run() {
- while(true){
- condition.b();
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- };
- }
- package com.citi.test.mutiplethread.demo5;
- public class CCondition implements Runnable {
- private DemoCondition condition;
- public CCondition(DemoCondition condition) {
- this.condition = condition;
- }
- @Override
- public void run() {
- while(true){
- condition.c();
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
来源: http://www.bubuko.com/infodetail-3207212.html