一张图讲解对象锁和关键字synchronized修饰方法
每个对象在出生的时候就有一把钥匙(监视器Monitor),那么被synchronized 修饰的方法相当于给方法加了一个锁,这个方法就可以进行同步,在多线程的时候,不会出现线程安全问题。
注:Monitor是 Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。每一个对象都有,也仅有一个 Monitor。
下面通过一张图片进行讲解:
1.一张图片
图片看不清,请点击这里 : [高清大图](http://img.blog.csdn.net/20170929230249738?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDY0ODU1NQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
2.图片对应的代码
import java.util.Date;
/**
* 测试的object类
*
* @author:dufy
* @version:1.0.0
* @date 2017/9/29
* @email 742981086@qq.com
*/
public class ObjectTest {
public synchronized void methodA(){
try {
System.out.println("This is methodA ...." + Thread.currentThread().getName() + ": " + new Date());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void methodB(){
System.out.println("This is methodB ...." + Thread.currentThread().getName() + ": " + new Date());
}
public synchronized void methodC(){
try {
System.out.println("This is methodC ...." + Thread.currentThread().getName() + ": " + new Date());
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.dufy.concurrentcode;
/**
* 测试线程类
*
* @author:dufy
* @version:1.0.0
* @date 2017/9/29
* @email 742981086@qq.com
*/
public class ThreadTest extends Thread{
public static void main(String[] args) {
ObjectTest ot = new ObjectTest();
Thread1 t1 = new Thread1(ot,"thread1");
Thread2 t2 = new Thread2(ot,"thread2");
Thread3 t3 = new Thread3(ot,"thread3");
Thread4 t4 = new Thread4(ot,"thread4");
t1.start();
t2.start();
t3.start();
t4.start();
}
static class Thread1 extends Thread{
private ObjectTest objectTest;
public Thread1(ObjectTest objectTest,String name){
setName(name);
this.objectTest = objectTest;
}
@Override
public void run() {
super.run();
objectTest.methodA();
}
}
static class Thread2 extends Thread{
private ObjectTest objectTest;
public Thread2(ObjectTest objectTest,String name){
setName(name);
this.objectTest = objectTest;
}
@Override
public void run() {
super.run();
objectTest.methodB();
}
}
static class Thread3 extends Thread{
private ObjectTest objectTest;
public Thread3(ObjectTest objectTest,String name){
setName(name);
this.objectTest = objectTest;
}
@Override
public void run() {
super.run();
objectTest.methodA();
}
}
static class Thread4 extends Thread{
private ObjectTest objectTest;
public Thread4(ObjectTest objectTest,String name){
setName(name);
this.objectTest = objectTest;
}
@Override
public void run() {
super.run();
objectTest.methodC();
}
}
}
运行结果:
This is methodB ....thread2: Fri Sep 29 23:21:17 CST 2017
This is methodA ....thread1: Fri Sep 29 23:21:17 CST 2017
This is methodC ....thread4: Fri Sep 29 23:21:18 CST 2017
This is methodA ....thread3: Fri Sep 29 23:21:21 CST 2017
注:
1、运行的结果可能和上图讲的线程流程不同,没有关系,只要理解对象锁和synchronized的核心思想就好,线程的运行本来就是具有随机性这个特点。
2、此段代码是同步方法,其实同步的代码块也是一个道理,同步代码块用synchronized(this)时候,当一个线程访问object的一个synchronized(this)同步代码块的时候,其他线程对object中所有其他的synchronized(this)同步的代码块访问都被阻塞 (阻塞的是同步代码块,线程依然可以进入同步代码块的方法)。
3.总结
- 每个对象都有一把锁(对象监视器),关键字synchronized取得锁都是对象锁,而不是把一段代码或方法(函数)当做锁。
- 上图所示,哪个线程先执行带有synchronized关键字的方法,哪个线程就持有这个方法所属对象的钥匙。其他线程只能处于等待状态。
- 调用关键字synchronized声明的方法,一定是排队运行的。这才是使用synchronized关键字的作用,排队运行,如果有共享资源的话,那么共享资源的读取就是线程安全的。
- 如果一个线程持有 object的钥匙,那么其他线程可以访问object对象没有上锁的方法,也就是非synchronized类型的方法。
4.Monitor和线程关系
首先看一下线程和 Monitor之间关系,以 及线程的状态转换图。通过图讲解一下整个过程。
上图分为三块:Entry Set(进入区) 、The Owner(拥有区)、Wait Set(等待区)。
Entry Set(进入区):表示线程通过synchronized要求获取对象的锁。如果对象未被锁住,则迚入拥有者;否则则在进入区等待。一旦对象锁被其他线程释放,立即参与竞争。
The Owner(拥有区):表示某一线程成功竞争到对象锁。
Wait Set(等待区):表示线程通过对象的wait方法,释放对象的锁,并在等待区等待被唤醒。
从图中可以看出,一个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 “Active Thread”,而其它线程都是 “Waiting Thread”,分别在两个队列 “ Entry Set”和 “Wait Set”里面等候。
上面的内容讲解引自 :Java命令学习系列(二)——Jstack 中关于Monitor的讲解。
5.参考
**如果帅气(美丽)、睿智(聪颖),和我一样简单善良的你看到本篇博文中存在问题,请指出,我虚心接受你让我成长的批评,谢谢阅读!
祝你今天开心愉快!**
欢迎访问我的csdn博客,我们一同成长!
"不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!"
博客首页:http://blog.csdn.net/u010648555
一张图讲解对象锁和关键字synchronized修饰方法的更多相关文章
- 一张图讲解最少机器搭建FastDFS高可用分布式集群安装说明
很幸运参与零售云快消平台的公有云搭建及孵化项目.零售云快消平台源于零售云家电3C平台私有项目,是与公司业务强耦合的.为了适用于全场景全品类平台,集团要求项目平台化,我们抢先并承担了此任务.并由我来主 ...
- synchronized修饰方法和对象的区别
使用synchronized(object) { 代码块.... } 能对代码块进行加锁,不允许其他线程访问,其的作用原理是:在object内有一个变量,当有线程进入时,判断是否为0,如果为0,表示可 ...
- 一张图讲解单机FastDFS图片服务器安装步骤(修订版)
前面已经讲 一张图秒懂微服务的网络架构,通过此文章可以了解FastDFS组件中单机安装流程. 单机版架构图 以下为单机FastDFS安装步骤 一.环境准备 CentOS 7.X libfastcomm ...
- 一张图看懂JavaScript中数组的迭代方法:forEach、map、filter、reduce、every、some
好吧,竟然不能单发一张图,不够200字啊不够200字! 在<JavaScript高级程序设计>中,分门别类介绍了非常多数组方法,其中迭代方法里面有6种,这6种方法在实际项目有着非常广泛的作 ...
- 一张图讲解为什么需要自己搭建自己的git服务以及搭建的途径
图片信息量有点大.不废话上图 图中的一些链接: gitlab官方安装文档 https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/in ...
- 【java】学习路线5-public和private、构造方法、this关键字、封装对象、static关键字、main方法结构解析
//一个教务管理系统//知识点清单/*public & private 的区别一个是公开的,一个是私有的,作用域不一样,访问的权限不一样咯如果是用private修饰,则调用者只可以是在当前的作 ...
- Java 中对象锁和类锁的区别? 关键字 Synchronized的用法?
一 对象锁和类锁的关系 /* * 对象锁和[类锁] 全局锁的关系? 对象锁是用于对象实例方法,或者一个对象实例上的 this 类锁是用于类的静态方法或者一个类的class对象上的. Ag.class ...
- Synchronized方法锁、对象锁、类锁区别
synchronized,这个东西我们一般称之为”同步锁“,他在修饰代码块的时候需要传入一个引用对象作为“锁”的对象. 在修饰方法的时候,默认是当前对象作为锁的对象 在修饰类时,默认是当前类的Clas ...
- 干货 | 45张图庖丁解牛18种Queue,你知道几种?
在讲<21张图讲解集合的线程不安全>那一篇,我留了一个彩蛋,就是Queue(队列)还没有讲,这次我们重点来看看Java中的Queue家族,总共涉及到18种Queue.这篇恐怕是市面上最全最 ...
随机推荐
- 欠了好久的CRM帖子,双11来读。
又一年双11了,觉得天猫双11越来越没特色了. 从折扣,音符旋律到红包,今年15年却找不出往年的热度,只是商家还是一样的急,备着活动目标计划,做着库存价格打标视觉设计这种苦逼的日子. 欠了好久的CRM ...
- Ext.Msg.alert添加确定按钮
Ext.Msg.alert('成功','成功!!', function(btn){ if(btn!=null{//btn=='ok'||btn=='cancel' ... } });
- 下拉菜单效果和tab选项卡切换
//下拉菜单效果和tab选项卡切换. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...
- 即时通信系统Openfire分析之四:消息路由
两个人的孤独 两个人的孤独,大抵是,你每发出去一句话,都要经由无数网络.由几百个计算机处理后,出在他的面前,而他就在你不远处. 连接管理之后 Openfire使用MINA网络框架,并设置Connect ...
- snowflake主键生成策略
1.snowflake简介 在分布式系统中,我们需要各种各样的ID,既然是ID那么必然是要保证全局唯一,除此之外,不同当业务还需要不同的特性,比如像并发巨大的业务要求ID生成效率高,吞吐大:比如某些银 ...
- MySQL(五)DDL(数据定义语言)
SHOW CREATE TABLE 表名\G前言 前面在数据库的讲解中,其实很多东西都非常的细节,在以前的学习过程中我都是没有注意到的.可能在以后的工作中会碰到所以都是做了记录的. 接下来,我将分享的 ...
- 后端路由项目由 gulp 改为 webpack 的踩坑实录
前言 公司有个后端路由的项目是用 gulp 作为前端自动化构建工具,最近学习了一下 webpack,深感其强大,一狠心将其改成了 webpack 构建,以下是踩坑实录. gulp 先来说说原来的架构. ...
- 交换基本数据类型的方法swap,并影响到主方法
不知道朋友在哪里看到的问题,qq来问我,题目是:在不修改主方法的前提下使用一个方法交换两个int的值,方法如下: public static void main(String[] args) { In ...
- IOS学习【前言】
2016-1-14 16年开始时导师安排任务,开始IOS学习之旅 经过几天的学习,感觉还是需要作比较多的学习笔记,因此开始用博客记录整个过程,方便以后查看学习与分享. 主要记录一些关键的问题处理方法 ...
- 短视频 SDK 功能点技术实现方式详解
第三方短视频解决方案作为快速切入短视频行业的首选方式,选择一款功能齐全.性能优异的短视频解决方案十分重要. 今天我们来谈谈短视频 SDK 6大重要功能点及其技术实现方式. 短视频拍摄 断点续拍 指在拍 ...