java condition 使用

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

 

posted @ 2019-09-21 17:17  泥古拉斯赵四  阅读(3132)  评论(0编辑  收藏  举报