码迷,mamicode.com
首页 > 其他好文 > 详细

一张图讲解对象锁和关键字synchronized修饰方法

时间:2017-10-01 00:26:26      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:[]   extends   oid   read   rgs   调用   而不是   排队   线程   

每个对象在出生的时候就有一把钥匙(监视器),那么被synchronized 修饰的方法相当于给方法加了一个锁,这个方法就可以进行同步,在多线程的时候,不会出现线程安全问题。
下面通过一张图片进行讲解:

1.一张图片

图片看不清,请右键 ,新标页面打开查看大图

这里写图片描述

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(www.senta77.com/){
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 www.kinyl.com 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 www.thd1956.com/ objectTest;

public Thread3(ObjectTest www.8555388.cn/ 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 www.wanuoyl88.cn = objectTest;
}
@Override
public void run() {
super.run();
objectTest.methodC();

运行结果:

This is methodB ....www.lgzxyl.com thread2: Fri Sep 29 23:21:17 CST 2017
This is methodA ....www.wmyld11.cn thread1: Fri Sep 29 23:21:17 CST 2017
This is methodC ....www.88qusheng.cn thread4: Fri Sep 29 23:21:18 CST 2017
This is methodA ....www.yiqianou.cn thread3: Fri Sep 29 23:21:21 CST 2017
1
2
3
4
注:运行的结果可能和上图讲的线程流程不同,没有关系,只要理解对象锁和synchronized的核心思想就好,线程的运行本来就是具有随机性这个特点。

3.总结

每个对象都有一把锁,关键字synchronized取得锁都是对象锁,而不是把一段代码或方法(函数)当做锁。
上图所示,哪个线程先执行带有synchronized关键字的方法,哪个线程就持有这个方法所属对象的钥匙。其他线程只能处于等待状态。
调用关键字synchronized声明的方法,一定是排队运行的。这才是使用synchronized关键字的作用,排队运行,如果有共享资源的话,那么共享资源的读取就是线程安全的。
如果一个线程持有 object的钥匙,那么其他线程可以访问object对象没有上锁的方法,也就是非synchronized类型的方法。
4.参考

Java多线程编程核心技术


如果帅气(美丽)、睿智(聪颖),和我一样简单善良的你看到本篇博文中存在问题,请指出,我虚心接受你让我成长的批评,谢谢阅读!
祝你今天开心愉快!

欢迎访问我的csdn博客,我们一同成长!

“不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!”

一张图讲解对象锁和关键字synchronized修饰方法

标签:[]   extends   oid   read   rgs   调用   而不是   排队   线程   

原文地址:http://www.cnblogs.com/wanmeiyule/p/7616471.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!