ReentrantLock类

ReentrantLock

与synchronized相比有以下特点

  1. 可中断
  2. 可以设置为公平锁
  3. 支持多个条件变量

与sychronized一样的

  1. 支持可重入锁
  2. 可打断锁(避免死锁):使用lockInterruptibly()方法

public class TestReentrant {
    private static ReentrantLock lock=new ReentrantLock();
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            try {
                System.out.println("尝试获取锁");
                //如果没有竞争此方法会获取锁
                //有竞争则进入阻塞队列,可以被其他线程用interrupt方法打断
                lock.lockInterruptibly();
            } catch (InterruptedException i) {
                System.out.println("没有获取到锁");
                i.printStackTrace();
                return;
            }
            try {
                System.out.println("获取锁成功");
            } finally {
                lock.unlock();
            }
        });
        lock.lock();
        thread.start();	//主线程拿走锁,使thread线程进入阻塞状态
//        thread.interrupt();	//打断该线程避免死锁
    }
}

锁超时

  1. 设置锁超时
reentrantLock.tryLock(2, TimeUnit.SECONDS)//尝试获取锁获取锁成功返回true,失败返回false
reentrantLock.unLock();//该方法调用必须放在finally

条件变量:

可以创建多个,让某个线程进入该条件变量等待。唤醒时可以指定唤醒某个线程

Condition condition = lock.newCondition();  //创建一个条件变量,让某个线程在这里等待
Condition condition1 = lock.newCondition();
 try {
 	condition.await();  //让线程进入等待
   condition.signal(); //唤醒该条件变量中某个线程
   condition.signalAll();//唤醒该条件变量中的全部线程
} catch (InterruptedException e) {
   throw new RuntimeException(e);
} 

结合上面写个案例


package devise;

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

/**
 *
 * 小明没烟,要抽烟才能干活
 * 小红饿了,要吃外卖才能干活。
 * 但是在同一个房间休息小明抽烟会有烟味,小红吃不下。
 * 所以分了两房间
 * 
 */

public class TestCorrectPostureStep {

    static ReentrantLock lock=new ReentrantLock();
    static Condition c1=lock.newCondition();//房间c1
    static Condition c2=lock.newCondition();//房间c2
    static boolean cigarette =false;
    static boolean takeout =false;

    public static void main(String[] args){
        //小明
        Thread t1=new Thread(()->{
            lock.lock();
            try {
                while (!cigarette){
                    System.out.println("烟没到休息一会");
                    try {
                        c1.await(); //让小明到c1休息室休息
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.println("烟到了,开始干活");
            } finally {
                lock.unlock();
            }
        });
        //小红
        Thread t2 =new Thread(()->{
            lock.lock();
            try {
                while (!takeout){
                    System.out.println("外卖没到休息一会");
                    try {
                        c2.await();//让小红到c2休息室休息
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.println("外卖到了,开始干活");
            }finally {
                lock.unlock();
            }
        });

        //送外卖线程
        Thread t3=new Thread(()->{
            lock.lock();
            try {
                Thread.sleep(2000);
                cigarette=true;
                c1.signal();//唤醒小红让小明干活
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }finally {
                lock.unlock();
            }
        }); 
        //送烟线程
        Thread t4=new Thread(()->{
            lock.lock();
            try {
                Thread.sleep(2000);
                takeout=true;
                c2.signal(); //唤醒小明让小明干活
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }finally {
                lock.unlock();
            }
        });

        t1.start();
        t2.start();
        t3.start();
        t4.start();

    }}
posted @ 2024-06-09 20:50  csm~/  阅读(13)  评论(0)    收藏  举报