JAVA 并发编程之七:重入锁ReentrantLock + lock + condition :可选择唤醒特定线程(线程状态控制Type2)

版权声明:本文为博主原创文章,未经允许不得转载,如有问题,欢迎指正,谢谢! https://blog.csdn.net/cbk861110/article/details/89165029

前言:synchronized和ReentrantLock的区别:

1. 要注意synchronized同步,假如发生异常,JVM是可以帮我们自动释放锁的;但是lock不可以,我们只能手动释放锁,即使发生异常,jvm也不会自动释放锁。

2. synchronized与wait()和notify()/notifyAll()方法结合可以实现等待通知模式;Reentrantlock可以实现同样的功能,在synchronized当中,被通知的线程是由JVM随机选择,但是lock结合condition可以实现选择性通知。

ReentrantLock + lock + condition  使用举例:

备注:注意在condition.await()方法调用之前,必须先lock.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(); //1. Condition 通过Lock(ReentrantLock)生成
    public Condition conditionB=lock.newCondition(); 
    public void awaitA(){
        try {
            lock.lock();
            System.out.println("begin awaitA时间为"+System.currentTimeMillis()
                    +"ThreadName="+Thread.currentThread().getName());
            conditionA.await();
            System.out.println("end awaitA 时间为"+System.currentTimeMillis()
                    +"ThreadName"+Thread.currentThread().getName());
 
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            lock.unlock(); //2. 推荐方式:ReentrantLock 锁必须要手动unlock,建议放在finally 代码块中
        }
    }
 
    public void awaitB(){
        try {
            lock.lock();
            System.out.println("begin awaitB时间为"+System.currentTimeMillis()
                    +"ThreadName="+Thread.currentThread().getName());
            conditionB.await();
            System.out.println("end awaitB 时间为"+System.currentTimeMillis()
                    +"ThreadName"+Thread.currentThread().getName());
 
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    public void signalAll_A(){
        try {
            lock.lock();
            System.out.println("signalAll_A时间为"+System.currentTimeMillis()
                    +"ThreadName"+ Thread.currentThread().getName());
            conditionA.signalAll();
        }finally {
            lock.unlock();
        }
    }
    public void signalAll_B(){
        try {
            lock.lock();
            System.out.println("signalAll_B时间为"+System.currentTimeMillis()
                    +"ThreadName"+ Thread.currentThread().getName());
            conditionB.signalAll();
        }finally {
            lock.unlock();
        }
    }

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

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

 
public class test {
    public static void main(String args[]){
        MyService service=new MyService();
        ThreadA a=new ThreadA(service);
        a.setName("A");
 
        ThreadB b=new ThreadB(service);
        b.setName("B");
 
        a.start();
        b.start();
 
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        service.signalAll_A(); 
    }
}

资料整理来自:https://blog.csdn.net/awille/article/details/81869380

猜你喜欢

转载自blog.csdn.net/cbk861110/article/details/89165029