- 浏览: 130460 次
- 性别:
- 来自: ...
文章分类
最新评论
早在总结一时,我就尽量的把synchronized的重点说的简单:它就是配和对象的隐式锁使用的,注意一定是对象的隐式锁!那么下面的这个例子又怎么解释呢?
这里ImplicitLock有两个同步方法,一个是static的,一个是普通的。ImplicitLockSample是一个测试主程序,实例化一个ImplicitLock对象,并且开启两个线程,每个线程分别调用对象的method1和method2方法。每个进入方法的线程都会强制休眠3秒。那么执行的现象是什么呢?
要知道答案有以下几点要清楚:a.Class和Object的关系,b.static方法的含义,c.synchronized的机制,d.sleep的作用。清楚的知道这些之后,一眼就能辨别method1和method2方法上的synchronized配和的是两把不同的对象隐式锁。答案也就清晰的知道这两个线程执行的打印语句根本就不会相差近3秒的等待,而是几乎同时。下面我试着解释一下。
Class是Object的子类,说明了Class是特殊的对象,它自然也有对象隐式锁。static声明方法意味着这个方法不依赖于类的实例,而是可以理解成去掉了隐式参数this的,类对象的方法。synchronized是与对象隐式锁绑定的,这代表了将其置于方法声明上它将与方法的持有对象绑定。所以method1的同步锁是ImplicitLock类对象的隐式锁,而method2的同步锁是ImplicitLock实例对象的隐式锁。sleep虽然能让当前的线程休眠,但是它不会释放持有的隐式锁。这样主程序执行是虽然用同一个实例让两个线程分别去调用两个方法,但是它们之间并没有任何竞争锁的关系,所以几乎同时打印,不会有近3秒的间隔。把method1的调用改成已注释的代码将更容易理解。如果method1的synchronized去掉,或者method2加上synchronized的声明,那么它们将竞争同一个隐式锁。先获得锁的线程将在3秒后交出锁,后面的线程才能执行打印。
写这篇补遗源自于对懒汉式单例的重新理解,之前对synchronized的机制不明了时,只知道使用synchronized关键字在static方法上声明就能保证单例的线程安全,但是确不知道那算是误打误撞的理解。构造这个验证例子之前,static和synchronized的共同使用让我对synchronized隐式锁有了更清晰的认识。所以打算再写写来分享这段体会。
/** * User: yanxuxin * Date: Dec 17, 2009 * Time: 9:38:27 PM */ public class ImplicitLockSample { public static void main(String[] args) { final ImplicitLock sample = new ImplicitLock(); new Thread(new Runnable() { public void run() { // ImplicitLock.method1(); sample.method1(); } }).start(); new Thread(new Runnable() { public void run() { sample.method2(); } }).start(); } } class ImplicitLock { public static synchronized void method1() { System.out.println("method1 executing..."); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void method2() { System.out.println("method2 executing..."); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } }
这里ImplicitLock有两个同步方法,一个是static的,一个是普通的。ImplicitLockSample是一个测试主程序,实例化一个ImplicitLock对象,并且开启两个线程,每个线程分别调用对象的method1和method2方法。每个进入方法的线程都会强制休眠3秒。那么执行的现象是什么呢?
要知道答案有以下几点要清楚:a.Class和Object的关系,b.static方法的含义,c.synchronized的机制,d.sleep的作用。清楚的知道这些之后,一眼就能辨别method1和method2方法上的synchronized配和的是两把不同的对象隐式锁。答案也就清晰的知道这两个线程执行的打印语句根本就不会相差近3秒的等待,而是几乎同时。下面我试着解释一下。
Class是Object的子类,说明了Class是特殊的对象,它自然也有对象隐式锁。static声明方法意味着这个方法不依赖于类的实例,而是可以理解成去掉了隐式参数this的,类对象的方法。synchronized是与对象隐式锁绑定的,这代表了将其置于方法声明上它将与方法的持有对象绑定。所以method1的同步锁是ImplicitLock类对象的隐式锁,而method2的同步锁是ImplicitLock实例对象的隐式锁。sleep虽然能让当前的线程休眠,但是它不会释放持有的隐式锁。这样主程序执行是虽然用同一个实例让两个线程分别去调用两个方法,但是它们之间并没有任何竞争锁的关系,所以几乎同时打印,不会有近3秒的间隔。把method1的调用改成已注释的代码将更容易理解。如果method1的synchronized去掉,或者method2加上synchronized的声明,那么它们将竞争同一个隐式锁。先获得锁的线程将在3秒后交出锁,后面的线程才能执行打印。
写这篇补遗源自于对懒汉式单例的重新理解,之前对synchronized的机制不明了时,只知道使用synchronized关键字在static方法上声明就能保证单例的线程安全,但是确不知道那算是误打误撞的理解。构造这个验证例子之前,static和synchronized的共同使用让我对synchronized隐式锁有了更清晰的认识。所以打算再写写来分享这段体会。
发表评论
文章已被作者锁定,不允许评论。
-
一道位操作的趣味编程题
2010-03-14 10:50 2080看到一道很有意思的编程题:大厅里有64盏灯,每盏灯都编 ... -
一道字符串截取的编程题
2010-03-11 10:52 2272最近接触到一道字符串截取的编程题:编写一个截取字符串的 ... -
一道多线程趣味热身题
2010-02-28 18:01 1912保持对知识点或者技术的熟悉度对于程序员至关重要,要学会 ... -
疑似Google多线程面试题的Java实现
2010-02-24 17:39 4903来到一个完全陌生的地方,即将一切从新开始,内心兴奋又忐 ... -
Mina的线程池实现分析(2)
2010-02-10 17:31 4516分析了I/O事件的存储,下面看看多个Worker同时工 ... -
Mina的线程池实现分析(1)
2010-02-10 17:28 11571线程池是并发应用中,为了减少每个任务调用的开销增强性能 ... -
多线程基础总结十一--ConcurrentLinkedQueue
2010-02-03 17:52 12835ConcurrentLinkedQueue充分使用了a ... -
LinkedBlockingQueue应用--生产消费模型简单实现
2010-01-29 20:45 8132之前介绍时LinkedBlockingQueue提到了 ... -
多线程基础总结十--LinkedBlockingQueue
2010-01-28 14:33 15368随着多线程基础总结的增多,却明显的感觉知道的越来越少, ... -
号称放倒一片的一道J2SE基础题的个人理解
2010-01-23 14:07 2788近日无意中看到一道Java基础题,号称在接受测试的10 ... -
多线程基础总结九--Mina窥探(1)
2010-01-21 23:46 5393一直以来的多线程的基础总结都是脱离应用的,但是要说多线 ... -
多线程基础总结八--ReentrantReadWriteLock
2010-01-15 23:22 7506说到ReentrantReadWriteLock,首先 ... -
多线程基础总结七--ReentrantLock
2010-01-09 23:17 7672之前总结了部分无锁机制的多线程基础,理想的状态当然是利 ... -
关于atomic问题的一点理解
2009-12-30 16:42 2434之前看到一个帖子是关于atomic使用的,当时没有仔细 ... -
多线程基础总结五--atomic
2009-12-17 19:46 3545在简单介绍java.util.c ... -
多线程基础总结四--ThreadLocal
2009-12-16 19:48 2715说到ThreadLocal,首先 ... -
多线程基础总结三--volatile
2009-12-15 20:09 2521前面的两篇总结简 ... -
多线程基础总结二--Thread
2009-12-12 23:27 2663对于Thread来说 ... -
多线程基础总结一--synchronized(1)
2009-12-12 23:23 3066最近写关于并发的小应 ... -
由destory-method引发的IOC容器设计的思考
2009-12-07 16:51 1678第一次读Spring的源 ...
相关推荐
代码块和静态方法同对象,类锁 对比 对象锁不同对象,类锁 对比 对象锁同对象,类锁 对比 对象锁代码实现SyncDemoSyncThread总结synchronized底层实现原理实现synchronized基础对象在内存中的布局对象头结构Monitor...
就是当多个线程访问某一个类(对象或方法)时,这个类(对象或方法)始终都能表现出正确的行为,那么这个类(对象或方法)就是线程安全的。 1.2 synchronized关键字 可以在任意对象及方法上加锁,而加锁的这段代码称为...
一个java的多线程juc总结,其中包含基础知识,现成的状态图,关于synchronized,线程优先级和线程分类,interrupt、interupted、isInterrupted的使用,sleep、yield、join的详细使用,锁和等待池介绍。
一些关键且实用的Java开发技巧: 基础语法与规范: 始终使用public class并遵循驼峰命名法。 使用final关键字以提高性能和明确意图(不可变对象)。 明确初始化变量,避免...注意volatile关键字的使用,确保多线程
【多线程】简述synchronized 和java.util.concurrent.locks.Lock的异同? 90 【线程】ThreadLocal的作用 90 【Spring】什么是IOC和DI?DI是如何实现的 91 【Spring】spring中的IOC(控制反转)的原理 92 【Spring】...
与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...
我认为这本书是从Java多线程的基础迈向实际开发架构的指导 第一章走入并行世界: 介绍了并发的基础理论:同步/异步,并发/并行,临界区,阻塞/非阻塞,死锁/饥饿/活锁,并发级别,定律,JMM中的原子性,可见性,有序...
3.4 小结:基本数据类型—— Java中一切数据和运算的基础 63 3.5 习题 65 第4章 Java中的程序执行流程 67 教学视频:1小时57分钟 4.1 顺序执行 67 4.2 使用if-else让程序懂得判断 68 4.2.1 if语句 68 4.2.2 ...
3.4 小结:基本数据类型—— Java中一切数据和运算的基础 63 3.5 习题 65 第4章 Java中的程序执行流程 67 教学视频:1小时57分钟 4.1 顺序执行 67 4.2 使用if-else让程序懂得判断 68 4.2.1 if语句 68 4.2.2 ...
分享到:更多0 前言 Map 这样的 Key Value 在软件开发中是非常经典的结构,常用于在内存中存放数据。 本篇主要想讨论 ConcurrentHashMap 这样一个并发容器,在正式开始之前我觉得有必要谈谈 HashMap,没有它就不会...
50、多线程有几种实现方法?同步有几种实现方法? 33 51、启动一个线程是用run()还是start()? . 33 52、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? 33 53、线程的基本概念...
2.设计模式是比 J2EE 等框架软件更小的体系结构,J2EE 中许多具体程序都是应用设计模式来完成的,当你深入到 J2EE 的内 部代码研究时,这点尤其明显,因此,如果你不具备设计模式的基础知识(GoF 的设计模式),你很难...