Java多线程学习之synchronized总结
0、概述
synchronized是Java提供的内置的锁机制,来实现代对码块的同步访问,称为内置锁(Intrinsic Lock) 。内置锁包括两部分:一个是作为锁的对象的引用,另一个是由这个锁保护的代码块。需要理解的是,synchronized的锁都是对象的引用,同一个对象只有一个内置锁,不同的对象有不同的内置锁。
Java 的内置锁是一种互斥锁,即一个对象的锁只能同时被一个线程持有。假设线程A尝试获取线程B持有的锁,线程A会被阻塞,知道B释放该锁,A才能持有该锁。如果线程B永远不是释放该锁,线程A也将永远等待下去,形成死锁。 由于线程在等待内置锁的过程中无法被中断,这是synchronized内置锁的一个弊端,该需求可以被显示锁ReentranLock解决,可以参考这篇博客:http://www.cnblogs.com/moongeek/p/7857794.html。
获得一个对象内置锁的唯一途径就是进入由该对象锁保护的代码块,释放锁的唯一途径是跳出该代码块。一般synchronized使用方法如下:
synchronized(lock){
// 访问或修改由该锁保护的共享状态
}
1、synchronized的使用
synchronized可以修饰一般方法、static方法、代码块,但是不论synchronized修饰什么,他获取的都是一个对象的内置锁,锁的单位都是对象。
1)synchronized 修饰一般方法,锁是持有该方法的对象的锁,访问同一个类的相同方法时候会互斥。
public synchronized void doSomething(){
// ...
}
上代码等价于:
public void doSomething(){
synchronized(this){
// ...
}
}
2)synchronized 修饰代码块,锁是指定的对象的锁,如果是同一个对象的锁,那么会互斥访问。
// 锁为object对象的锁
synchronized(object){ }
3)synchronized 修饰静态方法,锁是该类Class对象的锁,该类的所有对象访问该类时都会互斥。
public class Demo{
public synchronized static void doSomething(){
// ...
}
}
上代码等价于:
public class Demo{
public static void doSomething(){
synchronized(Demo.class){
// ...
}
}
}
2、可重入性
当某个线程请求一个已经被其他线程持有的锁时,该线程会被阻塞。但是内置锁是可重入的,因此,如果一个内置锁尝试获得已经由他自己持有的锁,那这个请求会立即成功。“重入”意味着获取锁的操作粒度是“线程”而不是”调用“。
重入的实现方法是,为每个所关联一个锁和一个计数值。当计数值为0时,这个锁就被认为是没有被任何线程持有。当线程请求一个未被持有的线程时,JVM记下这个持有者,并且将计数值增1.如果同一个线程再次获得这个锁,计数值将增加,而当线程退出同步代码块时,计数器相应的递减。当计数值为0,这个锁将被释放。
public class Test {
private Object lock;
public synchronized void saySomething(){
}
public synchronized void doSomething(){
// 两个函数都是同一个对象锁,可重入
saySomething();
}
public void goSomewhere(){
// 对象锁不一致,不能重入
synchronized (lock){
saySomething();
}
}
}
Java多线程学习之synchronized总结的更多相关文章
- Java多线程学习(二)synchronized关键字(2)
转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79670775 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...
- Java多线程学习(二)synchronized关键字(1)
转载请备注地址: https://blog.csdn.net/qq_34337272/article/details/79655194 Java多线程学习(二)将分为两篇文章介绍synchronize ...
- Java多线程学习(转载)
Java多线程学习(转载) 时间:2015-03-14 13:53:14 阅读:137413 评论:4 收藏:3 [点我收藏+] 转载 :http://blog ...
- java多线程学习笔记——详细
一.线程类 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...
- 【转】Java多线程学习
来源:http://www.cnblogs.com/samzeng/p/3546084.html Java多线程学习总结--线程概述及创建线程的方式(1) 在Java开发中,多线程是很常用的,用得好的 ...
- JAVA多线程学习笔记(1)
JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...
- Java多线程学习(六)Lock锁的使用
系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...
- Java多线程学习(五)线程间通信知识点补充
系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...
- Java多线程学习(四)等待/通知(wait/notify)机制
转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79690279 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...
随机推荐
- HTTP协议、HTTP协议原理分析
百度百科中说明: 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议.所有的WWW文件都必须遵守这个标准.设计HTTP最初的目的是为 ...
- Python3.5 学习八
#动态导入 官方建议import importlibimport_str="lib.aa"lib=importlib.import_module(import_str)obj=li ...
- 【xsy1058】 单词 乱搞
题目大意:给你$n$个长度为$m$的字符串,字符集仅为{x,y,z}三个字符,定义两个字符串$(s_i,s_j)$的相似度为$\sum_{k=1}^{m} [s_i[k]==s_j[k]]$. 从$0 ...
- 用postman做接口测试实例
使用postman做接口测试,可以选择请求方式,可以直接输入参数和header,可以编写测试结果的代码,判断是否通过测试 下图为填写接口测试地址.填写接口的参数,点击send发送请求 其中,Param ...
- Mac下的paths.d目录神奇用法
首先,这个方法是通过PG的做法学到的,且这个方法只能在Mac下用,在Linux下还真没有这个方法. 这个paths.d的作用很简单,就是在里面创建一个文件,然后写上需要在全局命令行下用到的命令,直接配 ...
- EF基础知识小记一
1.EF等ORM解决方案出现的原因 因为软件开发中分析和解决问题的方法已经接近成熟,然后关系型数据库却没有,很多年来,数据依然是保存在表行列这样的模式里,所以,在面相对象和高度标准化的数据库中产生了一 ...
- 【转】Entity framework 6 编写的通用数据类
原文:http://blog.csdn.net/laokaizzz/article/details/25730813 准备参考
- wp 自定义分页函数
function kerui_pagination($query_string){ global $posts_per_page, $paged; $my_query = new WP_Query($ ...
- Java性能调优:利用VisualVM进行性能分析
JVisualVM 简介 VisualVM 是Netbeans的profile子项目,已在JDK6.0 update 7 中自带,能够监控线程,内存情况,查看方法的CPU时间和内存中的对 象,已被GC ...
- xgboost与gbdt区别
1.基分类器的选择:传统GBDT以CART作为基分类器,XGBoost还支持线性分类器,这个时候XGBoost相当于带L1和L2正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题). 2.二阶泰 ...