天天看點

Condition接口(又稱條件對象)1.作用2.代碼示範

@[toc]

1.作用

  • 當線程1需要等待某個條件的時候 ,它就去執行 condition.await() 方法,一旦執行了 await()方法,線程就會進入阻塞狀态
  • 然後通常會有另外一個線程,假設是線程2,去執行對應的條件,知道這個條件成立,線程2就會去執行condition.signal() 方法,這是 JVM 就會被從阻塞的線程裡找到那些等待該condition的線程,當線程1就會收到可執行信号的時候,他的線程狀态就會變成Runnable 可執行狀态

signalAll() 和signal() 差別

: signalAll() 會喚醒所有的正在等待的線程

: 但是signal是公平的,隻會喚起那個等待時間最長的線程

package com.yxl.task;


import lombok.SneakyThrows;
import org.omg.PortableInterceptor.INACTIVE;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Condition 示範demo
 */
public class ConditionDemo {

    private ReentrantLock lock = new ReentrantLock();

    private Condition condition = lock.newCondition();

    //方法1
    void method1(){
        lock.lock();
        try {
            System.out.println("條件不滿足,開始await");
            condition.await();
            System.out.println("條件滿足了,開始執行後續");

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    //方法2
    void method2() {
        lock.lock();
        try {
            System.out.println("準備工作完成,喚醒其他線程 ");
            condition.signal();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ConditionDemo conditionDemo =new ConditionDemo();
        new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                Thread.sleep(1000);
                conditionDemo.method2();
            }
        }).start();
        conditionDemo.method1();
    }
}           

執行結果:

條件不滿足,開始await

準備工作完成,喚醒其他線程

條件滿足了,開始執行後續

2.代碼示範

  • 生産着消費者案例
package com.yxl.task;


import lombok.SneakyThrows;
import org.omg.PortableInterceptor.INACTIVE;
import org.omg.PortableServer.THREAD_POLICY_ID;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.PriorityQueue;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Condition 實作生産者 消費者
 */
public class ConditionDemo {

    private int queueSize = 10 ;
    //隊列
    private PriorityQueue queue =new PriorityQueue(queueSize);
    //lock鎖
    private ReentrantLock lock = new ReentrantLock();

    private Condition notFull = lock.newCondition();
    private Condition notEmpty = lock.newCondition();

    //方法1
    class Consumer extends Thread {
        @SneakyThrows
        @Override
        public void run() {
            comsume();
        }
        private void comsume() throws InterruptedException {
            while (true){
                lock.lock();
                try {
                    while (queue.size() == 0) {
                        System.out.println("隊列空,等待資料");
                        notEmpty.await();
                    }
                    queue.poll();
                    notFull.signalAll();
                    System.out.println("從隊列裡驅走了一個資料,剩下"+ queue.size());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }

            }

        }
    }


    class Produce extends Thread {
        @SneakyThrows
        @Override
        public void run() {
            produce();
        }
        private void produce() throws InterruptedException {
            while (true){
                lock.lock();
                try {
                    while (queue.size() == queueSize) {
                        System.out.println("隊列滿,等待空閑");
                        notFull.await();
                    }
                    queue.offer(1);
                    notEmpty.signalAll();
                    System.out.println("向隊列插入一個元素"+ queue.size());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }

            }

        }
    }

    public static void main(String[] args) {
        ConditionDemo conditionDemo =new ConditionDemo();
        Produce produce = conditionDemo.new Produce();
        Consumer consumer = conditionDemo.new Consumer();
        consumer.start();
        produce.start();
    }
}           
Condition接口(又稱條件對象)1.作用2.代碼示範

#

Condition接口(又稱條件對象)1.作用2.代碼示範

有興趣的同學可以看下源碼實作 和 JDK 介紹