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. VUE.js 中取得后台原生HTML字符串 原样显示问题

    今天使用vue调试页面,发现了页面上的一个问题,后台数据传过来的HTML字符串并没有被转换为正常的HTML代码,一拍脑门,发现忘记转换了,于是满心欢喜加上了{{{}}}.但是之后构建发现报错: 为此去 ...

  2. LINQ to SQL语句大全

    LINQ to SQL语句大全     LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判 ...

  3. day 59 pymysql

    PyMySQL介绍 PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2中则使用mysqldb. PYmysql安装 pip install pymys ...

  4. pandas 对dataframe一列中某些值进行处理

    https://github.com/Bifzivkar/Boutique-Travel-Services-Predict/blob/master/feature/5_extract_feature. ...

  5. 七,mysql优化——表的垂直划分和水平划分

    1,表的水平划分 如果一个表的记录数太多,比如成千上万条,而且需要经常检索,那么我们有必要化整为零.如果我拆成100个表,那么每个表只有10万条记录.当然需要数据在逻辑上可以划分.一个好的划分依据,有 ...

  6. [Dart]语法基础

    此页面向您展示如何使用每个主要Dart功能,从变量和运算符到类和库,假设您已经知道如何使用其他语言编程. 要了解有关Dart核心库的更多信息,请参阅 Dart Libraries之旅.无论何时需要有关 ...

  7. Python 3 虚拟机端口映射 VMware

    编程语言(以Python 3 为例子) 编程语言最开始就是机器语言(低级语言,计算机能认识:0101... 最底层的指令代码),学习很困难.现在用机器语言的很少,芯片厂商的技术人员来编程之外:发展下来 ...

  8. linux下shell脚本执行方法及exec和source命令

    exec和source都属于bash内部命令(builtins commands),在bash下输入man exec或man source可以查看所有的内部命令信息. bash shell的命令分为两 ...

  9. Django中url的反向查询

    明确几个概念: application namespace:   正在部署的app的名称,一个app的多个实例应该具有相同的application namespace.   可以通过在URLconf模 ...

  10. C++ 实现Biginteger

    网上C++版Biginteger参差不齐,一下子没有找到一个令人满意Biginteger,最近用c++改写了一下C#版 BigInteger,可以用于RSA大素数的生成,分享给大家.也请大家批评指正改 ...