多線程 condition 使用

Condition是在java 1.5中才出現的,它用來替代傳統的Object的wait()、notify()實現線程間的協作,相比使用Object的wait()、notify(),使用Condition的await()、signal()這種方式實現線程間協作更加安全和高效。因此通常來說比較推薦使用Condition,阻塞隊列實際上是使用了Condition來模擬線程間協作。

  • Condition是個接口,基本的方法就是await()和signal()方法
  • Condition依賴於Lock接口,生成一個Condition的基本代碼是lock.newCondition()
  • 調用Condition的await()和signal()方法,都必須在lock保護之內,就是說必須在lock.lock()和lock.unlock之間纔可以使用
  • Conditon中的await()對應Object的wait()
  • Condition中的signal()對應Object的notify()
  • Condition中的signalAll()對應Object的notifyAll()

多線程下使用

public class ConditionTest2 {

    private final static Lock lock = new ReentrantLock();

    private final static Condition PRODUCE_COND = lock.newCondition();

    private final static Condition CONSUME_COND = lock.newCondition();

    private final static LinkedList<Long> TIMESTAMP_POOL = new LinkedList<>();

    private final static int MAX_CAPACITY = 100;

    public static void produce(){
        try {
            lock.lock();
            while(TIMESTAMP_POOL.size() >= MAX_CAPACITY){
                PRODUCE_COND.await();
            }
            long value = System.currentTimeMillis();
            System.out.println(Thread.currentThread().getName() + "-p-" + value);
            TIMESTAMP_POOL.addLast(value);
            CONSUME_COND.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void consume(){
        try {
            lock.lock();
            while (TIMESTAMP_POOL.isEmpty()){
                CONSUME_COND.await();
            }
            long value = System.currentTimeMillis();
            System.out.println(Thread.currentThread().getName() + "-C-" + value);
            PRODUCE_COND.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        // 測試的時候,線程中請加上時間sleep
        new Thread(()->{
            for (;;){
                produce();
            }
        }).start();

        new Thread(()->{
            for (;;){
                produce();
            }
        }).start();

        new Thread(()->{
            for (;;){
                consume();
            }
        }).start();

        new Thread(()->{
            for (;;){
                consume();
            }
        }).start();
    }
}

https://blog.csdn.net/fuyuwei2015/article/details/72602182
這裏講的很詳細

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章