Java多线程学习笔记(五) 使用Condition实现等待/通知

1. 使用Condition

在使用notify()/notifyAll()方法进行通知时,被通知的线程是由JVM随机选择的。但使用ReentrantLock类结合Condition类可以实现“选择性通知”,这个功能是相当重要的。

1.1 MyService

public class MyService {

    private Lock lock = new ReentrantLock();
    public Condition condition = lock.newCondition();

    public void await(){
        try{
            lock.lock();
            System.out.println("await time is " + System.currentTimeMillis());
            condition.await();
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void signal(){
        try{
            lock.lock();
            System.out.println("signal time is " + System.currentTimeMillis());
            condition.signal();
        }finally {
            lock.unlock();
        }
    }
}

1.2 ThreadA

public class ThreadA extends Thread {
    private MyService service;

    public ThreadA(MyService service){
        super();
        this.service = service;
    }

    @Override
    public void run(){
        service.await();
    }
}

1.3 Test

public class Test {
    public static void main(String[] args) throws InterruptedException {
        MyService service = new MyService();
        ThreadA a = new ThreadA(service);
        a.start();

        Thread.sleep(3000);
        service.signal();
    }
}

1.4 运行结果

await time is 1541569098094
signal time is 1541569101095

1.5 方法对比

Object类 Condition类
wait() await()
wait(long timeout) await(long time, TimeUnit unit)
notify() signal()
notifyAll() signalAll()

2. 使用多个Condition实现通知部分线程

2.1 MyService

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MyService {
    private Lock lock = new ReentrantLock();
    public Condition conditionA = lock.newCondition();
    public Condition conditionB = lock.newCondition();

    //region await
    public void awaitA(){
        try{
            lock.lock();
            System.out.println("begin awaitA");
            conditionA.await();
            System.out.println("end awaitA");
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void awaitB(){
        try{
            lock.lock();
            System.out.println("begin awaitB");
            conditionB.await();
            System.out.println("end awaitB");
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    //endregion

    //region signalAll
    public void signalAll_A(){
        try{
            lock.lock();
            System.out.println("signalAll_A");
            conditionA.signalAll();
        }finally {
            lock.unlock();
        }
    }

    public void signalAll_B(){
        try{
            lock.lock();
            System.out.println("signalAll_B");
            conditionB.signalAll();
        }finally {
            lock.unlock();
        }
    }
    //endregion
}

2.2 ThreadA

public class ThreadA extends Thread {
    private MyService service;

    public ThreadA(MyService service){
        super();
        this.service = service;
    }

    @Override
    public void run(){
        service.awaitA();
    }
}

2.3 ThreadB

public class ThreadB extends Thread {
    private MyService service;

    public ThreadB(MyService service){
        super();
        this.service = service;
    }

    @Override
    public void run(){
        service.awaitB();
    }
}

2.4 Test

public class Test {
    public static void main(String[] args) throws InterruptedException {
        MyService service = new MyService();

        ThreadA a = new ThreadA(service);
        a.setName("A");
        a.start();

        ThreadB b = new ThreadB(service);
        b.setName("B");
        b.start();

        Thread.sleep(3000);
        service.signalAll_A();
    }
}

2.5 运行结果

begin awaitA
begin awaitB
signalAll_A
end awaitA

猜你喜欢

转载自blog.csdn.net/winterking3/article/details/83820924
今日推荐