Java进阶:ReentrantLock和Condition基本使用

it2023-11-02  74

1. 概述

Java除了使用synchronized锁之外,还可以使用ReentrantLock实现独占锁。ReentrantLock使用起来更加灵活,也提供了更丰富的功能。

2. 加锁解锁

验证加锁之前,先来看一段没加锁的代码

public class ReentrantLockApp { static class MyTest{ public volatile int num = 0; //自增 public void incr(){ this.num++; } } public static void main(String[] args) throws InterruptedException { MyTest myTest = new MyTest(); //10个线程,每个线程自增1000次 for (int i = 1; i <= 10; i++){ new Thread(() -> { for (int j = 1; j <= 1000; j++){ myTest.incr(); } }, "Thread" + i).start(); } while (Thread.activeCount() > 2){ Thread.yield(); } System.out.println(myTest.num); } }

由于num++本身就不是线程安全的计算,所以在多线程环境下结果是异常的:

D:\Java\jdk\jdk1.8_131\bin\java.exe 9712 Process finished with exit code 0

使用ReentrantLock加锁

static class MyTest{ public Lock lock = new ReentrantLock(); public volatile int num = 0; public void incr(){ lock.lock(); try { this.num ++; } catch (Exception ex){ ex.printStackTrace(); } finally { lock.unlock(); } } }

输出结果

D:\Java\jdk\jdk1.8_131\bin\java.exe 10000 Process finished with exit code 0

3. Condition

Condition 是 Java 提供用来实现等待/通知的类,它由lock对象创建,调用await()使当前线程进入阻塞,调用signal()唤醒该线程继续执行。

看个例子:

static class MyTest { public Lock lock = new ReentrantLock(); //创建lock对象 public Condition condition = lock.newCondition(); //创建condition public void await(){ lock.lock(); try{ System.out.println("await开始时间:" + new Date()); condition.await(); //线程进入堵塞 System.out.println("await结束时间:" + new Date()); } catch (Exception ex){ ex.printStackTrace(); } finally { lock.unlock(); } } public void signal(){ lock.lock(); try{ System.out.println("signal时间:" + new Date()); condition.signal(); //唤醒该condition } catch (Exception ex){ ex.printStackTrace(); } finally { lock.unlock(); } } } public static void main(String[] args) throws InterruptedException { MyTest myTest = new MyTest(); new Thread(() -> { myTest.await(); }).start(); Thread.sleep(3000); //等待3秒再执行下面的唤醒 new Thread(() -> { myTest.signal(); }).start(); Thread.sleep(3000); }

输出如下,可见await开始和await结束间隔3秒

await开始时间:Tue Oct 20 22:52:46 CST 2020 signal时间:Tue Oct 20 22:52:49 CST 2020 await结束时间:Tue Oct 20 22:52:49 CST 2020 Process finished with exit code 0
最新回复(0)