什么是锁?
时间:2022-07-25
本文章向大家介绍什么是锁?,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
什么是锁?
说到锁,门闩,密码锁,指纹锁,虹膜识别锁等,在计算机世界中,单机线程没有锁的概念,当有了资源竞争,才有锁的贵爱安出现。表示自己短暂的持有。
计算机锁从最开始的悲观锁,然后发展到后来的乐观锁,偏向锁,分段锁等。
锁有两种特性:互斥性和不可见性。
JUC 中的锁
并发包的类族,Lock 是 JUC 包的顶层接口。实现逻辑并未用到 synchronized ,而是利用 volatile 的可见性。
Lock 的继承类图,ReentrantLock 对于 Lock 接口的实现主要依赖了 Sync, 而 Sync 继承了 AbstractQueuedSynchronizer(AQS), AQS 是实现同步的基础工具。
在 AQS 中定义了,定义了一个 volatile int state 变量作为共享资源,如果线程获取资源失败,则进入 同步的 FIFO 队列;如果成功获取资源就执行临界区代码。
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
}
AQS 的子类可以定义不同性质的方法。
- 比如可重入锁 ReentrantLock ,定义 State 为0 时,可以获取资源并设置1,如果已经获得资源,state 不断+1 ,释放资源 state-1 直到为0;
- CountDown 初始化定义资源总量 state=count ,CountDown() 不断将 state-1 ,所以 CountDownLatch 是一次性的,用完之后只能重建一个,如果要循环使用,推进使用 CyclicBarrier 。
- Semaphore 与 CountDownLatch 不同,定义了资源总量 state=permits. 当state >0 就可以获得锁,并将 state-1.当 state=0时只能等待其他线程释放锁。当释放锁时 state+1。当 Semaphore 的permits定义为1时,为互斥锁。permits>1 为共享锁。
CyclicBarrier 例子
每次 await 都会 count-1
int index = --count;
测试代码:
public class CyclicBarrierSample {
/**
* @param args
*/
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(5, new Runnable() {
@Override
public void run() {
System.out.println("Action.... go again!");
}
});
for (int i = 0; i < 5; i++) {
Thread t = new Thread(new CyclicWorker(barrier));
t.start();
}
}
}
class CyclicWorker implements Runnable {
private CyclicBarrier barrier;
public CyclicWorker(CyclicBarrier barrier) {
this.barrier = barrier;
}
/**
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
try {
for (int i = 0; i < 3; i++) {
System.out.println("Executed!");
barrier.await();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
CountDownLatch 代码
public class LatchSample {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(6);
for(int i = 0; i < 5 ; i++){
Thread t = new Thread(new FirstBatchWorker(latch));
t.start();
}
for(int i = 0 ; i < 5;i++){
Thread t = new Thread(new SecondBatchWorker(latch));
t.start();
}
while(latch.getCount() != 1){
Thread.sleep(100L);
}
System.out.println(" wait gor first batch finish");
latch.countDown();
}
}
class FirstBatchWorker implements Runnable {
private CountDownLatch latch;
public FirstBatchWorker(CountDownLatch latch) {
this.latch = latch;
}
/**
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
System.out.println("First batch executed!");
latch.countDown();
}
}
class SecondBatchWorker implements Runnable {
private CountDownLatch latch;
public SecondBatchWorker(CountDownLatch latch) {
this.latch = latch;
}
@Override
public void run() {
try {
latch.await();
System.out.println("Second batch Executed!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- HDUOJ---1133(卡特兰数扩展)Buy the Ticket
- HDUOJ--2079选课时间(题目已修改,注意读题)
- HDUOJ---2082
- HDUOJ---2152
- nyoj-----D的小L
- HDUOJ---The Moving Points
- HDUOJ---------Kia's Calculation
- HDUOJ----Good Numbers
- DP较为完整的知识
- HDUOJ----The Number Off of FFF
- HDUOJ-------Naive and Silly Muggles
- HDUOJ----A Computer Graphics Problem
- HDUOJ---(4708)Herding
- HDUOJ---(4708)Rotation Lock Puzzle
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 一天一大 lee(回文子串)难度:中等-Day20200819
- 一天一大 lee(组合)难度:中等-Day20200908
- es6学习笔记
- 一天一大 lee(图像渲染)难度:简单-Day20200816
- 一天一大 lee(前 K 个高频元素)难度:中等-Day20200907
- 一天一大 lee(二叉树的层次遍历 II)难度:简单-Day20200906
- 一天一大 lee(第k个排列)难度:中等-Day20200905
- 一天一大 lee(二叉树的所有路径)难度:简单-Day20200904
- 一天一大 lee(N 皇后)难度:困难-Day20200903
- 一天一大 lee(二叉树的中序遍历)难度:中等-Day20200914
- 一天一大 lee(二叉树的层平均值)难度:简单-Day20200912
- 一天一大 lee(组合总和 II)难度:中等-Day20200910
- 一天一大 lee(组合总和 III)难度:中等-Day20200911
- 一天一大 lee(翻转二叉树)难度:简单-Day20200916
- 一天一大 lee(表示数值的字符串)难度:中等-Day20200902