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总结的更多相关文章

  1. Java多线程学习(二)synchronized关键字(2)

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79670775 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  2. Java多线程学习(二)synchronized关键字(1)

    转载请备注地址: https://blog.csdn.net/qq_34337272/article/details/79655194 Java多线程学习(二)将分为两篇文章介绍synchronize ...

  3. Java多线程学习(转载)

    Java多线程学习(转载) 时间:2015-03-14 13:53:14      阅读:137413      评论:4      收藏:3      [点我收藏+] 转载 :http://blog ...

  4. java多线程学习笔记——详细

    一.线程类  1.新建状态(New):新创建了一个线程对象.        2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...

  5. 【转】Java多线程学习

    来源:http://www.cnblogs.com/samzeng/p/3546084.html Java多线程学习总结--线程概述及创建线程的方式(1) 在Java开发中,多线程是很常用的,用得好的 ...

  6. JAVA多线程学习笔记(1)

    JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...

  7. Java多线程学习(六)Lock锁的使用

    系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...

  8. Java多线程学习(五)线程间通信知识点补充

    系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...

  9. Java多线程学习(四)等待/通知(wait/notify)机制

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79690279 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

随机推荐

  1. Cordova - 实现热更新 !

    Cordova版本:8.0.0 更新APP平台:Android 操作系统:Windows Cordova的热更新,作用是把www内的变动部分更新到APP中,实现主程序不动,完成更新!!这个热更新功能, ...

  2. 伸展树的实现——c++

     一.介绍 伸展树(Splay Tree)是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.它由Daniel Sleator和Robert Tarjan创造.(01) 伸展树属于二叉 ...

  3. Segment Tree-732. My Calendar III

    Implement a MyCalendarThree class to store your events. A new event can always be added. Your class ...

  4. Flask从入门到精通之Flask表单渲染成HTML

    表单字段是可调用的,在模板中调用后会渲染成HTML.假设视图函数把一个NameForm 实例通过参数form 传入模板,在模板中可以生成一个简单的表单,如下所示: <form method=&q ...

  5. [bug]微信小程序使用 <scroll-view> 和 box-shadow 引起页面抖动

    背景 为了实现点点点动态loading效果,并且方便使用(只需要给一个空元素加一个.loading),有如下代码: .loader { background-color: #fff; font-siz ...

  6. MySQL 高级查询操作

    目录 MySQL 高级查询操作 一.预告 二.简单查询 三.显示筛选 四.存储过程 五.查询语句 1.作为变量 2.函数调用 3.写入数据表 备注 附表一 附表二 相关文献 博客提示 MySQL 高级 ...

  7. Centos下用yum命令按照jdk

    一.查看是否已经安装了JDK #查看本机是否已经安装了jdk $ sudo yum list installed | grep java java--openjdk.x86_64 :.el7_6 @u ...

  8. LeetCode题解-147 对链表进行插入排序 Medium

    对链表进行插入排序. 插入排序的动画演示如上.从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示). 每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中. 插 ...

  9. gephi

    http://pan.baidu.com/share/link?shareid=382396&uk=1696102437

  10. wildfly8+jpa EntityBean 简单入门

    1)首先配置wildfly的数据源,我使用的是mysql数据库 1.jboss7开始,jboss使用模块化设计所以数据源的配置也是遵循模块化. 打开wildfly的安装目录进入modules\syst ...