java并发编程:锁的相关概念介绍
理解同步,最好先把java中锁相关的概念弄清楚,有助于我们更好的去理解、学习同步。java语言中与锁有关的几个概念主要是:可重入锁、读写锁、可中断锁、公平锁
一、可重入锁
synchronized和ReentrantLock都属于可重入锁,当前加锁的程序调用了一个持有当前锁对象的子程序不会发生阻塞,代码如下
public synchronized void method2(){
System.out.println("method2");
}
public synchronized void method1(){
System.out.println("method1");
method2();
}
执行method1()方法,获取锁,然后又调用同步方法method2(),这个时候线程不需要申请method2()的锁,可以直接执行
如果synchronized不具备可重入性,线程A持有对象锁,进入method1方法,这个时候就要重新申请锁,但是这个锁其实就是线程A进入method1方法持有的锁,这样的话,线程A会一直等待一个永远获取不到的锁,所以synchronized和Lock都具备可重入性
二、读写锁
读写锁是将对一个资源的访问分成了两个锁:读锁和写锁
读写锁中、读读不互斥、只有涉及到写锁才互斥
ReadWriteLock是读写锁的根接口,实现类是ReentrantReadWriteLock(他们并没有实现Lock接口)
通过readLock()获取读锁、writeLock()获取写锁
三、可中断锁
就是可以响应中断的锁。synchronized属于不可中断锁,Lock则是可中断锁
如果线程A正在执行锁包住的代码,线程B等待获取该锁,有可能等待时间太长,线程B想去做别的事,我们可以让他中断自己或者在别的线程中断他。lock类使用lockInterruptibly()方法来实现可中断性,代码如下:
package com.xhy.lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class LockInterruptTest { private Lock lock = new ReentrantLock(); public static void main(String[] args) {
LockInterruptTest test = new LockInterruptTest();
MyThread myThread1 = new MyThread(test);
MyThread myThread2 = new MyThread(test);
myThread1.start();
myThread2.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
myThread2.interrupt();
// 处于等待中的线程2可以被正常终端(只有在调用lockInterruptibly()方法的情况下)
} public void insert() throws InterruptedException {
lock.lockInterruptibly();
// lock.lock();
try {
System.out.println(Thread.currentThread().getName() + "获得了锁");
while (true){ }
}finally {
System.out.println(Thread.currentThread().getName() + "执行了finally");
lock.unlock();
System.out.println(Thread.currentThread().getName() + "释放了锁");
}
}
} class MyThread extends Thread{
private LockInterruptTest test; public MyThread(LockInterruptTest test){
this.test = test;
} @Override
public void run() {
try {
test.insert();
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + "中断");
} }
}
运行结果如下
四、公平锁
公平锁就是排队来获取锁,这个队是请求的顺序,不能抢占。非公平锁不能保证获取锁的顺序是按照请求锁的顺序来的。这样可能有的线程很难获取到锁,或者永远获取不到,哈哈
synchronized属于非公平锁,对ReentrantLock和ReentrantReadWriteLock,它们默认情况下也不是公平锁,通过构造方法可以指定,代码如下:
/**
* Creates an instance of {@code ReentrantLock} with the
* given fairness policy.
*
* @param fair {@code true} if this lock should use a fair ordering policy
*/
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
/**
* Creates an instance of {@code ReentrantLock} with the
* given fairness policy.
*
* @param fair {@code true} if this lock should use a fair ordering policy
*/
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
它们里面定义了两个静态内部类,一个是NoFailSync,一个是FairSync,分别用来实现公平与否
java并发编程:锁的相关概念介绍的更多相关文章
- Java并发编程锁系列之ReentrantLock对象总结
Java并发编程锁系列之ReentrantLock对象总结 在Java并发编程中,根据不同维度来区分锁的话,锁可以分为十五种.ReentranckLock就是其中的多个分类. 本文主要内容:重入锁理解 ...
- java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock
原文:java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock 锁 锁是用来控制多个线程访问共享资源的方式,java中可以使用synch ...
- Java并发编程锁之独占公平锁与非公平锁比较
Java并发编程锁之独占公平锁与非公平锁比较 公平锁和非公平锁理解: 在上一篇文章中,我们知道了非公平锁.其实Java中还存在着公平锁呢.公平二字怎么理解呢?和我们现实理解是一样的.大家去排队本着先来 ...
- Java并发编程-volatile可见性的介绍
要学习好Java的多线程,就一定得对volatile关键字的作用机制了熟于胸.最近博主看了大量关于volatile的相关博客,对其有了一点初步的理解和认识,下面通过自己的话叙述整理一遍. 有什么用? ...
- java并发编程[持续更新]
目录 java并发编程 1.常用类介绍 Semaphore 2.名词解释 2.1 线程安全 2.2 可重入锁和不可重入锁 java并发编程 1.常用类介绍 Semaphore Semaphore 类是 ...
- Java 并发编程 | 线程池详解
原文: https://chenmingyu.top/concurrent-threadpool/ 线程池 线程池用来处理异步任务或者并发执行的任务 优点: 重复利用已创建的线程,减少创建和销毁线程造 ...
- [转载] java并发编程:Lock(线程锁)
作者:海子 原文链接: http://www.cnblogs.com/dolphin0520/p/3923167.html 出处:http://www.cnblogs.com/dolphin0520/ ...
- 【Java并发编程实战】----- AQS(二):获取锁、释放锁
上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...
- 【Java并发编程实战】-----“J.U.C”:CLH队列锁
在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格按照FIFO的队列.他能够确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...
- Java并发编程:Synchronized底层优化(偏向锁、轻量级锁)
Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) Java 并发编程 ...
随机推荐
- LC 712. Minimum ASCII Delete Sum for Two Strings
Given two strings s1, s2, find the lowest ASCII sum of deleted characters to make two strings equal. ...
- LC 667. Beautiful Arrangement II
Given two integers n and k, you need to construct a list which contains n different positive integer ...
- 解决 JDK1.7 不支持 VCenter 6.7 的问题(涉及到Https TLS1.2协议)
解决 JDK1.7 不支持 VCenter 6.7 的问题 问题描述 原项目工程是使用JDK 1.7,可以连接 5.X版本和 6.0版本的 VCenter资源池. 但是,现在VCenter已经升到 6 ...
- linux常用命令(7)cp命令
cp命令用来复制文件或者目录,是Linux系统中最常用的命令之一.一般情况下,shell会设置一个别名,在命令行下复制文件时,如果目标文件已经存在,就会询问是否覆盖,不管你是否使用-i参数.但是如果是 ...
- Initializer for conditional binding must have Optional type, not 'String'
今天看到问Swift问题: Initializer for conditional binding must have Optional type, not 'String' 以前没遇到过这个问题, ...
- Python操作SQLite
1. 导入sqlite3数据库模块,从python2.5以后,sqlite3成为内置模块,不需要额外安装,只需要导入即可. import sqlite3 2.创建/打开数据库 使用connect方法打 ...
- Golang中基础的命令行模块urfave/cli
前言相信只要部署过线上服务,都知道启动参数一定是必不可少的,当你在不同的网络.硬件.软件环境下去启动一个服务的时候,总会有一些启动参数是不确定的,这时候就需要通过命令行模块去解析这些参数,urfave ...
- swoole前置基础知识 进程间通信
进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息. IPC的方式通常有管道(包括无名管道和命名管道).消息队列.信号量.共享存储.Socket ...
- base64图片数据类型转numpy的ndarray矩阵类型数据
1.两种方法如下链接 https://www.cnblogs.com/mtcnn/p/9411683.html 2.第一种方法: # coding: utf-8 # python base64 编解码 ...
- 客户端数据存储cookie、localStoeage、sessionStorage(小记)
一.数据存储分为客户端存储和服务端存储 1.而对于客户端存储,在html5以前只能通过cookie来实现:html 5以后增加了web存储(实际保存本地)的功能 (1)对于web存储有两个标准: ...