Synchronized的前因后果
为什么要锁
当多个线程要对同一个目标进行修改的时候,为了保证数据的一致性,有序性,所以进行加锁。
通过对一个对象进行加锁,只有一个线程拿到这个对象,才能执行一段代码。
Synchronized的特性
- 原子性
- 可见性
“对一个变量unlock操作之前,必须要同步到主内存中;如果对一个变量进行lock操作,则将会清空工作内存中此变量的值,在执行引擎使用此变量前,需要重新从主内存中load操作或assign操作初始化变量值” 来保证的;
- 但是不保证有序性
synchronized的基本知识点
synchronized方法的变型
synchronized关键字实际修饰的是一个Object 类,类似于synchronized(Object o), 如果直接修饰synchronized 方法,则等同于
锁的是该类的this对象。
package juc.sync;public class T1 {private int count = 0;private static int count1 = 0;private Object obj = new Object();public void m() {synchronized(obj) {count++;System.out.println(Thread.currentThread().getName() + "count="+count);}}public synchronized void m1() {count++;System.out.println("等同于synchronized(this)");}public synchronized static void m2() {count1++;System.out.println("等同于synchronized(T1.class)");}public static void main(String[] args) {}}
同步方法和非同步方法可否一起调用?
答案是可以,非同步方法没有任何锁,当然这段代码可以被多个线程随时访问。
package juc.sync;
//同步方法和不同步的方法可否一起调用
public class T3 {public synchronized void m1() {try {Thread.sleep(200);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(Thread.currentThread().getName() + "synchronized");}public void m2() {try {Thread.sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(Thread.currentThread().getName() + "not synchronized");}public static void main(String[] args) {T3 t = new T3();
// new Thread(()-> {
// t.m1();
// }).start();new Thread(t::m1,"t1").start();
// new Thread(()-> {
// t.m2();
// }).start(); new Thread(t::m2,"t2").start();}
}
Synchronized可重入?
可重入的意思是一个同步方法是否可以调用另一个同步方法?可以,因为第一个方法拿的是一个对象锁,到第二方法的时候发现它也是同一把锁的话,是允许调用第二个方法的代码块的。
package juc.sync;public class T4 {synchronized void m1() {try {Thread.sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}m2();System.out.println(Thread.currentThread().getName() + "调用完m2");}synchronized void m2() {try {Thread.sleep(200);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(Thread.currentThread().getName() + "m2 end");}public static void main(String[] args) {T4 t = new T4();t.m1();}
}
该线程发生议程会释放锁
- 同步队列和等待队列的区别
- 同步队列指得是在runnable的线程,正在准备竞争锁的队列,如果锁被占用了,就会一直在同步队列里
- 等待队列指的是在wait的线程,比如线程正在wait的,sleep的都会放到等待队列,等到被notify或者时间到了,就可以进入同步队列去竞争锁了。
JVM的锁的底层实现
hotspot的实现,是锁的对象上面有一个64位的markword,64位中的2位用来判断对象是否被锁。
JDK早期都是重量级,就是直接对OS去申请这个锁,效率非常低。
现在采取了锁升级的方法。
比如我们sync(Object o)
o上有一个markword
锁升级的过程
1)最开始Object o的时候是无锁态。
2)然后有线程A要进去,就在这个锁(门)上打上一个标记A,偏向锁,告诉这样下次线程A再进来的时候看到标记A,就可以直接进去了。也就是在markword上记录这个线程ID
3) 如果这个时候线程B再来,就要和线程A竞争锁(门),这个通过CAS的过程来竞争,就是读门上的标签,如果为空,就去把线程B的地址写到门上,但写的过程发现标签变了,就自旋等待。
4)如果自旋的线程超过一定数量,就会触发锁升级到重量级/系统锁,就全部进入锁的队列中,不再自旋等待了。
自旋锁和系统锁的选择
自旋锁是消耗CPU, 而系统锁会引起阻塞。
线程的执行时间短且线程少可以用自旋锁,否则用重量级锁
无锁CAS-> 锁的优化
CAS并不是通过加OS锁,
为了解决syncronize的性能问题,使用CAS来解决,不需要加同步锁
CAS(value, expected,NewValue)
先是判断当前读出来的value值与expected进行比较,如果相当则更新为新值V, 如果不相等,就要重新读取value值,一直等到相等的时候,更新为新值V。所以这个线程会一直自旋在那里等待着两值相等。
- Atomic类
- AtomicInteger类
Synchronized的前因后果相关推荐
- 读书|《静心冥想的练习》:体验超越一切理解的平静与快乐
冥想是瑜伽实现入定的一项技法和途径,把心.意.灵完全专注在原始之初之中,最终目的在于把人引导到解脱的境界.瑜伽者通过冥想来制服心灵,并超脱物质欲念:感受到和原始动因直接沟通.通过简单练习冥想,即可帮助 ...
- 【java线程】锁机制:synchronized、Lock、Condition
[Java线程]锁机制:synchronized.Lock.Condition 原创 2013年08月14日 17:15:55 标签:Java /多线程 74967 http://www.infoq. ...
- java static 可见性_Java多线程 synchronized与可见性的关系以及可见性问题总结
作者:七里香的编程之路 出自:OSCHINA 原文:my.oschina.net/u/4098550/blog/4548274 能保证可见性的措施 除了volatile 可以让变量保证可见性外.hap ...
- 你真的掌握了并发编程volatile synchronized么?
先看代码: import java.util.concurrent.atomic.AtomicInteger;/**** @author xialuomantian*/ public class Ne ...
- Java使用字节码和汇编语言同步分析volatile,synchronized的底层实现
关于怎么查看字节码的五种方法参考本人另一篇文章<Java以及IDEA下查看字节码的五种方法> 查看汇编语言汇编码 说要看汇编还是很有必要的,因为有些地方比如加锁其实还是通过汇编实现的,只看 ...
- java并发vol_java 并发中 volitile、synchronized和lock的比较(一)
1.volitile和(synchronnized.lock) 首先比较volitile和synchronnized,volitile线程不安全,但是synchronized则是线程安全的. voli ...
- synchronized底层原理_你用过synchronized吗?它的底层原理是什么?Java经典面试题来了...
并发编程已经成为程序员必备技能 作为Java程序员,不懂得并发编程显然已经不能满足市场需求了,尤其是在面试过程中将处于被动地位,也有可能面试将就此终结. 那么作为Java开发者的你,日常虽然可以基于J ...
- 面试题-自旋锁,以及jvm对synchronized的优化
背景 想要弄清楚这些问题,需要弄清楚其他的很多问题. 比如,对象,而对象本身又可以延伸出很多其他的问题. 我们平时不过只是在使用对象而已,怎么使用?就是new 对象.这只是语法层面的使用,相当于会了一 ...
- JAVA多线程之Synchronized、wait、notify实例讲解
一.Synchronized synchronized中文解释是同步,那么什么是同步呢,解释就是程序中用于控制不同线程间操作发生相对顺序的机制,通俗来讲就是2点,第一要有多线程,第二当多个线程同时竞争 ...
最新文章
- 数据科学家必须要掌握的5种聚类算法
- linux 网卡流量脚本,每5分钟统计Linux 网卡流量的脚本
- php获取全部post_php post获取所有提交
- UVa10911 Forming Quiz Teams(dp)
- Windows环境下spyder调用Arcpy
- 这份门禁系统培训PPT也太全面了,门禁系统知识,看这一篇就够了
- 宏碁e5572g57mx加固态_宏基e5572g57mx怎么拆机
- scp 安全复制(远程文件复制工具)
- 分享实录 | 深度学习技术红利下的代码补全
- 第二章:Java基本语法
- 浅谈MVC MVP MVVM
- c语言数字和字母输出的,请问这个用c怎么做:输入一串字符,分别统计其中数字和字母的个数...
- stack 和 heap区别
- 苹果发布新iPhone SE,售价3299元起;百度网盘破解者被捕;GitHub核心功能免费开放 | 极客头条...
- 【最短路】Walls
- 咖说丨破碎的互联网下,加密技术正在恢复数据主权!
- .NET EF(Entity Framework)详解
- python和java就业对比_Python,Java和JavaScript哪个更容易就业?
- Extending Laravel with First Party Packages 用第一方软件包扩展Laravel Lynda课程中文字幕
- 英语不好学java好学吗_英语不好能学好java,做程序员吗?