Java ReentrantLock
2018-02-11 15:49
267 查看
ReentrantLock是Lock接口的实现,除了实现Lock接口的功能,还提供了getHoldCount()和getQueueLengt()两个方法,分别用于获取目前加锁数量和等待获取锁队列的长度。 使用的时候,要保证加锁必须有解锁,否则会导致死锁,为了保证最后能够解锁,一定要在最后使用finally将unlock方法紧紧裹住。
class X { private final ReentrantLock lock = new ReentrantLock(); // ... public void m() { lock.lock(); // block until condition holds try { // ... method body } finally { lock.unlock() } } }
/** * Created by LvJianwei on 2018/2/9. */ import java.util.concurrent.locks.ReentrantLock; import static sun.misc.Version.println; /** * @program: ReentrantLockDemo * @description: ReentrantLockDemo * @author: LvJianwei * @create: 2018-02-09 14:41 **/ public class ReentrantLockDemo { public static void main(String[] args) { ReentrantLockDemo demo = new ReentrantLockDemo(); Runnable rAdd = () -> { try { Thread.sleep(1000); demo.countAdd(); } catch (InterruptedException e) { e.printStackTrace(); } }; Runnable rReduce = () -> { try { Thread.sleep(1000); demo.countReduce(); } catch (InterruptedException e) { e.printStackTrace(); } }; for (int i = 0; i < 5; i++) { Thread t = new Thread(rReduce); t.start(); } for (int i = 0; i < 5; i++) { Thread t = new Thread(rAdd); t.start(); } } private ReentrantLock locker = new ReentrantLock(); public int count = 0; public void caculateWithoutLock() { countAdd(); countReduce(); } public synchronized void caculate() { countAdd(); countReduce(); printLockStatus(); longTimeLock(); } public void caculateWithLock() { locker.lock(); locker.getHoldCount(); try { countAdd(); countReduce(); printLockStatus(); longTimeLock(); } finally { locker.unlock(); } } public void countAdd() { locker.lock(); try { count++; System.out.printf("Add,count:%d\n", count); printLockStatus(); longTimeLock(); } finally { locker.unlock(); } } public void countReduce() { locker.lock(); try { count--; System.out.printf("reduce,count:%d\n", count); printLockStatus(); longTimeLock(); } finally { locker.unlock(); } printLockStatus(); } public void longTimeLock() { locker.lock(); try { int locktime = 3000; System.out.printf("longTimeLock:%d ms\n", locktime); printLockStatus(); Thread.sleep(locktime); } catch (InterruptedException e) { e.printStackTrace(); } finally { locker.unlock(); } printLockStatus(); } private void printLockStatus() { System.out.printf("thread id:%d,lock count:%d,queueLength:%d\n", Thread.currentThread().getId(), locker.getHoldCount(), locker.getQueueLength()); } }
countAdd方法和countReduce争夺count的计算,由于加锁,不论如何运行,最终结果都是0。
同一个线程可以添加多个锁,但是必须都要解锁才能释放,代码中增加一个longTimeLock用于多加一把锁,每一个线程执行的时候都会输出当前锁的数量和排队线程的数量,随着程序的执行,排队数量逐渐减少。
Add,count:1
thread id:17,lock count:1,queueLength:9
longTimeLock:3000 ms
thread id:17,lock count:2,queueLength:9
thread id:17,lock count:1,queueLength:9
thread id:17,lock count:0,queueLength:9
-----------------------
reduce,count:0
thread id:11,lock count:1,queueLength:8
longTimeLock:3000 ms
thread id:11,lock count:2,queueLength:8
thread id:11,lock count:1,queueLength:8
reduce,count:-1
thread id:15,lock count:1,queueLength:7
longTimeLock:3000 ms
thread id:15,lock count:2,queueLength:7
thread id:11,lock count:0,queueLength:7
-----------------------
thread id:15,lock count:1,queueLength:7
thread id:15,lock count:0,queueLength:7
-----------------------
reduce,count:-2
thread id:13,lock count:1,queueLength:6
longTimeLock:3000 ms
thread id:13,lock count:2,queueLength:6
thread id:13,lock count:1,queueLength:6
thread id:13,lock count:0,queueLength:6
-----------------------
reduce,count:-3
thread id:14,lock count:1,queueLength:5
longTimeLock:3000 ms
thread id:14,lock count:2,queueLength:5
thread id:14,lock count:1,queueLength:5
thread id:14,lock count:0,queueLength:5
-----------------------
Add,count:-2
thread id:18,lock count:1,queueLength:4
longTimeLock:3000 ms
thread id:18,lock count:2,queueLength:4
thread id:18,lock count:1,queueLength:4
thread id:18,lock count:0,queueLength:4
-----------------------
Add,count:-1
thread id:16,lock count:1,queueLength:3
longTimeLock:3000 ms
thread id:16,lock count:2,queueLength:3
thread id:16,lock count:1,queueLength:3
thread id:16,lock count:0,queueLength:3
-----------------------
reduce,count:-2
thread id:12,lock count:1,queueLength:2
longTimeLock:3000 ms
thread id:12,lock count:2,queueLength:2
thread id:12,lock count:1,queueLength:2
thread id:12,lock count:0,queueLength:2
-----------------------
Add,count:-1
thread id:20,lock count:1,queueLength:1
longTimeLock:3000 ms
thread id:20,lock count:2,queueLength:1
thread id:20,lock count:1,queueLength:1
thread id:20,lock count:0,queueLength:1
-----------------------
Add,count:0
thread id:19,lock count:1,queueLength:0
longTimeLock:3000 ms
thread id:19,lock count:2,queueLength:0
thread id:19,lock count:1,queueLength:0
thread id:19,lock count:0,queueLength:0
-----------------------
Process finished with exit code 0
相关文章推荐
- java 可重入读写锁 ReentrantReadWriteLock 详解
- Java多线程编程-(7)-使用ReentrantReadWriteLock实现Lock并发
- 《深入浅出 Java Concurrency》—锁机制(九) 读写锁 (ReentrantReadWriteLock) (2)
- 【Java并发】- ReentrantLock,重入锁
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- Java多线程同步(锁)的实现方法(synchronised 与reentrantlock)
- Java多线程(九)之ReentrantLock与Condition
- Java多线程11:ReentrantLock的使用和Condition
- Java高并发程序-Chapter3 JDK并发包(第十七讲)同步控制之ReentrantLock 的实现
- 深入浅出 Java Concurrency (14): 锁机制 part 9 读写锁 (ReentrantReadWriteLock) (2)
- 深入理解Java并发机制(4)--AQS、ReentrantLock、ReentrantReadWriteLock源码分析
- 【死磕Java并发】-----J.U.C之读写锁:ReentrantReadWriteLock
- Java并发编程之ReenTrantLock
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- Java:多线程,线程同步,同步锁(Lock)的使用(ReentrantLock、ReentrantReadWriteLock)
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- 轻松学习java可重入锁(ReentrantLock)的实现原理
- Java进阶知识--Synchronized、Lock、ReentrantLock的区别
- Java多线程(九)之ReentrantLock与Condition
- Java中的ReentrantLock和synchronized两种锁定机制的对比