传统的线程锁机制需要依赖synchronized同步与Object类中的wait()方法,notify()方法进行控制.然而这样的控制并不容易,所以在JUC,中提供有一个新的锁框架.在此框架中提供两个核心接口: Lock接口:支持各种不同语义(“公平机制锁”,“非公平机制锁”“可重入锁”)的锁规则; ReadWriteLock:接口:针对线程的读或写提供不同的锁处理机制,在数据读取时采用共享锁,数据修改时使用独占锁,这样就可以保证数据访问的性能;
ReentrantLock
ReentrantLoclk提供了一种互斥锁机制,这样在同一个时间点内只允许有一个线程持有该锁,而其他线程将进行等待与重新获取操作,ReentrantLocl最大的特点在与它也属于一个可重入锁,这就意味着该锁可以被单个线程重复获取 ReentrantLock分为FairSync(公平锁)和NofairSync(非公平锁),它们的区别体现在获取锁的机制上是否公平.锁是为了保护竞争资源,放在多个线程同时操作线程而出错.所以ReentrantLock在同一个时间点只能被一个线程获取,而所有未获取到锁的现行就必须进行等待,同时为了方便其他线程继续获取锁,ReentrantLock通过一个FIFO的队列来管理所以等待的线程. 公平锁:只有在当前线程是CLH等待队列的表头时,才获取锁; 非公平锁:当前锁处于空闲状态则直接获取,不管CLH等待队列中的顺序.
下面是用ReentrantLock模仿售票
public class Ticket { //总票数 private int count = 50; //互斥锁(独占锁) private ReentrantLock reentrantLock=new ReentrantLock(); public void sal(){ try { this.reentrantLock.lock(); if (count>0){ count--; System.out.println(Thread.currentThread().getName()+"成功卖出一张,剩余:"+count); }else { System.out.println("票卖完了!"); } } catch (Exception e) { e.printStackTrace(); }finally { //接触锁定 this.reentrantLock.unlock(); } } } package com; /** * @Authro: QYF * @Time:2020/10/8 22:24 */ public class JUCDemo { public static void main(String[] args) { Ticket ticket = new Ticket(); for (int i = 0; i < 60; i++) { new Thread(()->{ ticket.sal(); },"售票员"+i).start(); } } }输出结果:
售票员0成功卖出一张,剩余:49 售票员3成功卖出一张,剩余:48 售票员1成功卖出一张,剩余:47 售票员6成功卖出一张,剩余:46 售票员2成功卖出一张,剩余:45 售票员4成功卖出一张,剩余:44 售票员5成功卖出一张,剩余:43 售票员7成功卖出一张,剩余:42 售票员9成功卖出一张,剩余:41 售票员8成功卖出一张,剩余:40 售票员10成功卖出一张,剩余:39 售票员11成功卖出一张,剩余:38 售票员12成功卖出一张,剩余:37 售票员13成功卖出一张,剩余:36 售票员14成功卖出一张,剩余:35 售票员15成功卖出一张,剩余:34 售票员16成功卖出一张,剩余:33 售票员17成功卖出一张,剩余:32 售票员18成功卖出一张,剩余:31 售票员19成功卖出一张,剩余:30 售票员20成功卖出一张,剩余:29 售票员21成功卖出一张,剩余:28 售票员22成功卖出一张,剩余:27 售票员23成功卖出一张,剩余:26 售票员25成功卖出一张,剩余:25 售票员24成功卖出一张,剩余:24 售票员27成功卖出一张,剩余:23 售票员26成功卖出一张,剩余:22 售票员28成功卖出一张,剩余:21 售票员29成功卖出一张,剩余:20 售票员31成功卖出一张,剩余:19 售票员30成功卖出一张,剩余:18 售票员32成功卖出一张,剩余:17 售票员33成功卖出一张,剩余:16 售票员35成功卖出一张,剩余:15 售票员34成功卖出一张,剩余:14 售票员36成功卖出一张,剩余:13 售票员39成功卖出一张,剩余:12 售票员40成功卖出一张,剩余:11 售票员37成功卖出一张,剩余:10 售票员38成功卖出一张,剩余:9 售票员41成功卖出一张,剩余:8 售票员43成功卖出一张,剩余:7 售票员42成功卖出一张,剩余:6 售票员45成功卖出一张,剩余:5 售票员44成功卖出一张,剩余:4 售票员46成功卖出一张,剩余:3 售票员47成功卖出一张,剩余:2 售票员48成功卖出一张,剩余:1 售票员49成功卖出一张,剩余:0 票卖完了! 票卖完了! 票卖完了! 票卖完了! 票卖完了! 票卖完了! 票卖完了! 票卖完了! 票卖完了! 票卖完了! Process finished with exit code 0