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. flask源码解析之session

    内容回顾 cookie与session的区别: 1. session 是保存在服务端的键值对 2. cookie 只能保存4096个字节的数据,但是session不受限制 3. cookie保存在浏览 ...

  2. window / Linux 下 Golang 开发环境的配置

    一直专注于使用python语言进行程序开发,但是却又一直被它的性能问题所困扰,直到遇到了天生支持高并发的Golang,这似乎也成了学习go语言最理所当然的理由.下面介绍下Go语言开发环境搭建的步骤: ...

  3. python format()函数的用法

    Python format() 函数的用法 复制自博主 chunlaipiupiupiu 的博客,如有侵权,请联系删除 python中format函数用于字符串的格式化 通过关键字 1 print(' ...

  4. ssh 登陆 端口转发

    man ssh ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] [-D [bind_address:]port] ...

  5. getopt() getopt_long()函数手册[中文翻译]

    getopt()函数 getopt_long函数 函数原型(function prototype) #include <unistd.h> int getopt(int argc, cha ...

  6. WIKI常用的表格设计模板

    域名服务器管理表格     数据库管理表格     软件路径说明表格   开发测试环境虚拟机表格        

  7. AQS源码泛读,梳理设计流程(jdk8)

    一.AQS介绍 AQS(AbstractQueuedSynchronizer)抽象队列同步器,属于多线程编程的基本工具:JDK对其定义得很详细,并提供了多种常用的工具类(重入锁,读写锁,信号量,Cyc ...

  8. pymysql模块使用

    一.写函数的原因 写这个函数的原因就是为了能够不每次在用Python用数据库的时候还要在写一遍  做个通用函数做保留,也给大家做个小小的分享,函数不是最好的,希望有更好的代码的朋友能提出 互相学习 二 ...

  9. 移动端h5直播项目|html5直播实战开发|h5仿陌陌

    最近一些直播.小视频什么的都比较火,像陌陌.抖音.火山短视频… 于是空闲时间自己也利用html5技术也试着倒腾了下直播项目,使用到了h5+css3+iscroll+zepot+swiper+wlsPo ...

  10. Sequel简介

    Sequel: Ruby数据库工具包 简介 Sequel是Ruby中用于访问SQL数据库的一个简单.灵活.强大的工具包. Sequel能够保证线程安全,提供了连接池功能以及简洁的SDL用于创建SQL查 ...