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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM