博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Synchronized与ReentrantLock学习笔记
阅读量:3922 次
发布时间:2019-05-23

本文共 1322 字,大约阅读时间需要 4 分钟。

文章目录

如何解决线程并发安全问题?

所有的并发模式在解决线程安全问题时,采用的方案都是**序列化访问临界资源**。即在同一时刻,只能有一个 线程访问临界资源,也称作同步互斥访问。Java 中,提供了两种方式来实现同步互斥访问:synchronized和 Lock 同步器的本质就是加锁	 加锁目的:序列化访问临界资源,即同一时刻只能有一个线程访问临界资源(同步互斥访问)不过有一点需要区别 的是:当多个线程执行一个方法时,该方法内部的局部变量并不是临界资源,因为这些局部变量是在每个线程的私有栈中 因此不具有共享性,不会导致线程安全问题。

一、synchronized

1.使用方式

synchronized是对象锁,使用的时候需要传一个对象当成形参。	1、同步实例方法,锁是当前实例对象	2、同步类方法,锁是当前类对象	3、同步代码块,锁是括号里面的对象使用方式的具体代码,就不记录了

2.Monitor

synchronized关键字被编译成字节码后会被翻译成monitorenter 和 monitorexit 两条指令分别在同步块逻辑代码的起始位置与结束置。	在使用synchronized的同步方法或同步代码块中,会在方法开始的时候有一个monitorenter指令,在结束的时候有一个monitorexit指令。	具体Monitor代表什么我也不太清楚,就知道是每个对象都是一个Monitor,是用c++语言写的,这个没去研究了

3.锁升级(自己的白话总结)

1、无锁状态

无锁状态是使用了synchronized关键字的方法,在线程开始时没有用到或者锁已经消除。

2、偏向锁

当一个线程A首先获取到了锁,这个时候锁还没有消除,线程A再次去获取锁,发现此时的持有锁的是线程A,这个时候就让线程A再次获得锁并将锁升级为偏向锁。当这个线程再次请求锁时,无需再做任何同步操作,即获取锁的过程,这样就省去了大量有关锁申请的操作,从而也就提供程序的性能。	用处:当一个线程多次获取锁的时候可以减少线程开销。

3、轻量级锁

如果线程A已经获得了锁,线程B获取锁,这时候B肯定会获取锁失败。如果线程A此时刚好要结束,则撤销偏向锁升级为轻量级锁。在轻量级锁结束前,线程B会进入自旋锁状态,一直去获取锁,就相当于轮询了一定次数还没有获取锁,就停止轮询。升级为重量级锁。	用处:轻量级锁能够提升程序性能的依据是“对绝大部分的锁,在整个同步周期内都不存在竞争”

4、重量级锁

升级成重量级锁之后,就等A线程释放锁,再唤醒B线程获取锁。

还有一个逃逸分析就不在这个里面记录了

二、ReentrantLock

1.特性

  1. 阻塞等待队列
  2. 共享/独占
  3. 公平/非公平 (sync的两种实现)
  4. 可重入
  5. 允许中断(优雅的实现停止线程)

2.数据结构

在这里插入图片描述

3.具体实现

我的理解是根据state这个状态值去获取锁,唤醒锁的操作等等等等等等。感觉有好多知识点~害,还没有总结好,现在只是看了几遍源码,还不能去熟练总结。

总结

AQS很重要,因为阻塞队列用的也是加锁,然后阻塞队列会引入条件队列。后面的线程池、mq、dobbo等中间件都用到了阻塞队列。也是其它并发工具类的基础。

转载地址:http://aikgn.baihongyu.com/

你可能感兴趣的文章
Linux程序开发基础概念
查看>>
Linux系统环境变量详谈
查看>>
sprintf函数用法
查看>>
make的常见错误信息
查看>>
gdb命令手册
查看>>
gdb中设置共享库断点问题
查看>>
GBD调试程序(转)作者:Janlex
查看>>
OpenOBEX代码
查看>>
第16章可移植性
查看>>
linux下open()与fopen()
查看>>
小型软件公司的绩效考核
查看>>
程序编译中如何调试configure
查看>>
关于安装multiget出现XML::Parser perl module is required for intltool错误问题的解决
查看>>
从学习export命令理解到的Shell环境和变量生存期
查看>>
《程序员》杂志:小公司如何建设技术中层
查看>>
glibc是什么,以及与gcc的关系?
查看>>
转 arm-linux-gcc和arm-elf-gcc 区别
查看>>
使用 typedef 抑制劣质代码
查看>>
Bluez下的rfcomm层通信测试程序
查看>>
GCC参数详解
查看>>