ReentrantLock使用Condition实现通知部分线程

来源:互联网 发布:相册书制作软件 编辑:程序博客网 时间:2024/05/17 17:58

关键字synchronized与wait()和notify()/notifyAll()方法想结合可以实现等待/通知模式,类ReentrantLock也可以实现同样的功能,但需要借助于Condition对象。Condition类在JDK5中出现,使用它有更好的灵活性,比如可以实现多路通知的功能,也就是在一个Lock对象中可以创建多个Condition对象(对象监视器),线程对象可以注册在指定的Condition中,从而可以有选择地进行线程通知,在调度线程上更加灵活。

编程举例:
Service类,包含等待和通知的同步方法。

package lock;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();    public void awaitA(){        try{            lock.lock();            System.out.println("thread "+Thread.currentThread().getName()+" wait begin,in awaitA method");            conditionA.await(); //使用conditionA进行等待            System.out.println("thread "+Thread.currentThread().getName()+" end wait,in awaitA method");        }catch (InterruptedException e){            e.printStackTrace();        }finally {            lock.unlock();        }    }    public void awaitB(){        try{            lock.lock();            System.out.println("thread "+Thread.currentThread().getName()+" wait begin,in awaitB method");            conditionB.await();   //使用conditionB进行等待            System.out.println("thread "+Thread.currentThread().getName()+" end wait,in awaitB method");        }catch (InterruptedException e){            e.printStackTrace();        }finally {            lock.unlock();        }    }    public void signalAll_A(){        try{            lock.lock();            System.out.println("现在要通知所在在conditionA上等待的线程 "+Thread.currentThread().getName());            conditionA.signalAll();  //通知所有在conditionA上等待的线程        }finally {            lock.unlock();        }    }    public void signalAll_B(){        try{            lock.lock();            System.out.println("现在要通知所在在conditionB上等待的线程 "+Thread.currentThread().getName());            conditionB.signalAll();        }finally {            lock.unlock();        }    }}

线程A类,A类线程使用conditionA进行等待。

package lock;public class ThreadA extends Thread{    private MyService service;    public ThreadA(MyService service){        super();        this.service = service;    }    @Override    public void run(){        service.awaitA();    }}

B类线程,B类线程使用conditionB进行等待。

package lock;public class ThreadB extends Thread{    private MyService service;    public ThreadB(MyService service){        super();        this.service = service;    }    @Override    public void run(){        service.awaitB();    }}

测试类,调用Service类的signalAll_A方法,只通知在conditionA上等待的线程:

package lock;public class Run {    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();  //只通知在conditionA上等待的线程。    }}

程序输出如下:

thread A wait begin,in awaitA methodthread B wait begin,in awaitB method现在要通知所在在conditionA上等待的线程 mainthread A end wait,in awaitA method

由此可见线程B没有被唤醒。

在使用Condition实现等待通知时:
Object类中的wait()方法相当于Condition类的await()方法。
Object类中的wait(long timeout)方法相当于Condition类中的await(long time,TimeUnit unit)方法。
Object类中的notify()方法相当于Condition类中的signal()方法。
Object类中的notifyAll()方法相当于Condition类中的signalAll()方法。

参考《Java多线程编程核心技术》

0 0
原创粉丝点击