理解同步,最好先把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并发编程:锁的相关概念介绍的更多相关文章

  1. Java并发编程锁系列之ReentrantLock对象总结

    Java并发编程锁系列之ReentrantLock对象总结 在Java并发编程中,根据不同维度来区分锁的话,锁可以分为十五种.ReentranckLock就是其中的多个分类. 本文主要内容:重入锁理解 ...

  2. java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock

    原文:java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock 锁 锁是用来控制多个线程访问共享资源的方式,java中可以使用synch ...

  3. Java并发编程锁之独占公平锁与非公平锁比较

    Java并发编程锁之独占公平锁与非公平锁比较 公平锁和非公平锁理解: 在上一篇文章中,我们知道了非公平锁.其实Java中还存在着公平锁呢.公平二字怎么理解呢?和我们现实理解是一样的.大家去排队本着先来 ...

  4. Java并发编程-volatile可见性的介绍

    要学习好Java的多线程,就一定得对volatile关键字的作用机制了熟于胸.最近博主看了大量关于volatile的相关博客,对其有了一点初步的理解和认识,下面通过自己的话叙述整理一遍. 有什么用? ...

  5. java并发编程[持续更新]

    目录 java并发编程 1.常用类介绍 Semaphore 2.名词解释 2.1 线程安全 2.2 可重入锁和不可重入锁 java并发编程 1.常用类介绍 Semaphore Semaphore 类是 ...

  6. Java 并发编程 | 线程池详解

    原文: https://chenmingyu.top/concurrent-threadpool/ 线程池 线程池用来处理异步任务或者并发执行的任务 优点: 重复利用已创建的线程,减少创建和销毁线程造 ...

  7. [转载] java并发编程:Lock(线程锁)

    作者:海子 原文链接: http://www.cnblogs.com/dolphin0520/p/3923167.html 出处:http://www.cnblogs.com/dolphin0520/ ...

  8. 【Java并发编程实战】----- AQS(二):获取锁、释放锁

    上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...

  9. 【Java并发编程实战】-----“J.U.C”:CLH队列锁

    在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格按照FIFO的队列.他能够确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...

  10. Java并发编程:Synchronized底层优化(偏向锁、轻量级锁)

    Java并发编程系列: Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) Java 并发编程 ...

随机推荐

  1. vue.js-动态绑定class 利用index实现导航

    <template> <div class="stock"> <div class="buin_leftcont nav_ctrl" ...

  2. 自定义可拖动的Toast

    package com.loaderman.toastdemo; import android.content.Context; import android.graphics.PixelFormat ...

  3. Python获取两个文件的交集、并集、差集

    题记:朋友在处理数据时,需要解决这方面的问题,所以利用她给的代码,自己重新梳理了下,并成功运行. 代码如下: # coding:utf-8 s1 = set(open(r'C:\\Users\\yan ...

  4. k8s常用操作命令

    K8s常用命令操作 一.kubectl命令补全 .master安装命令补全,并临时生效 yum install -y bash-completion source /usr/share/bash-co ...

  5. redis外网无法连接问题

    1.外网无法连接redis 解决方法: 把redis.conf里的bind 127.0.0.1注释掉,不行的话把127.0.0.1修改成0.0.0.0 2.make的时候显示没有gcc 解决方法: 安 ...

  6. Leetcode之动态规划(DP)专题-72. 编辑距离(Edit Distance)

    Leetcode之动态规划(DP)专题-72. 编辑距离(Edit Distance) 给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 . 你可 ...

  7. Autofac依赖注入容器

    依赖注入容器-- Autofac https://github.com/danielpalme/IocPerformance Unity 更新频率高,微软的项目Grace 综合性能更高 目录: 一.简 ...

  8. 使用PowerShell 修改hosts

    直接上代码 # author:lttr <www.cnblogs.com/GoCircle> # date:2019-08-09[CmdletBinding()] param ( [Par ...

  9. 企业微信 PC端多开

    企业微信,正常情况下一个PC端只能登一个账号.现在多个人共用一个外网机,需要在一个电脑上登录多个账号.解决办法如下: 下载process explorer.exe,使用管理员权限运行,找到WXWork ...

  10. Django2.2 会话技术cookie session token的区别以及实例介绍

    一.区别: 本人见解:使用自定义数据项进行加密,作为唯一身份识别,登陆时写入cookie(session基于这个).在显示相关数据 1.cookie 属于客户端会话技术(数据存储在客户端) 默认的Co ...