基本上是从这篇文章转过来的:
http://developer.51cto.com/art/200908/143504.htm
1.对于同步方法和对象:
无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的不同对象访问。
解释一下“取得的锁都是对象”的意思:如果一个对象有多个synchronized方法,只要一个线程访问了这个对象中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法,但是对于不是synchronized的方法可以访问。而对于其他线程里的另一个对象可以访问synchronized方法。
2.对于同步块:
synchronized(要锁定的对象) {……}
当要锁定的对象为this时表示的是调用这个方法的对象。
3.对于同步static 方法:
不管调用方法的是类还是对象,锁定的都是类。即类被锁定了,只要一个线程中的对象或类访问了一个synchronized static方法,其他线程里的不管是类还是对象都不能再访问synchronized static方法了。
注:以上的对象即指一个类的实例。
再通过例子说明一下以上几点:
假设P1、P2是同一个类的不同对象,这个类中定义了以下几种情况的同步块或同步方法,P1、P2就都能够调用他们。
1. 把synchronized当作函数修饰符时,示例代码如下:
1. Public synchronized void method(){
2. //….
3. }
这也就是同步方法,那这时synchronized锁定的是哪个对象呢?他锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中 执行这个同步方法时,他们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却能够任意调用这个被加了 synchronized关键字的方法。
上边的示例代码等同于如下代码:
1. public void method()
2. {
3. synchronized (this) // (1)
4. {
5. //…..
6. }
7. }
(1)处的this指的是什么呢?他指的就是调用这个方法的对象,如P1。可见同步方法实质是将synchronized作用于object reference。――那个拿到了P1对象锁的线程,才能够调用P1的同步方法,而对P2而言,P1这个锁和他毫不相干,程式也可能在这种情形下摆脱同 步机制的控制,造成数据混乱。
2.同步块,示例代码如下:
1. public void method(SomeObject so) {
2. synchronized(so)
3. {
4. //…..
5. }
6. }
这时,锁就是so这个对象,谁拿到这个锁谁就能够运行他所控制的那段代码。当有一个明确的对象作为锁时,就能够这样写程式,但当没有明确的对象作为锁,只是想让一段代码同步时,能够创建一个特别的instance变量(他得是个对象)来充当锁:
1. class Foo implements Runnable
2. {
3. private byte[] lock = new byte[0]; // 特别的instance变量
4. Public void method()
5. {
6. synchronized(lock) { //… }
7. }
8. //…..
9. }
注:零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码。
3.将synchronized作用于static 函数,示例代码如下:
1. Class Foo
2. {
3. public synchronized static void method1() // 同步的static 函数
4. {
5. //….
6. }
7. public void method2()
8. {
9. synchronized(Foo.class) // class literal(类名称字面常量)
10. }
11. }
代码中的method2()方法是把class literal作为锁的情况,他和同步的static函数产生的效果是相同的,取得的锁很特别,是当前调用这个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)。
记得在《Effective Java》一书中看到过将 Foo.class和 P1.getClass()用于作同步锁还不相同,不能用P1.getClass()来达到锁这个Class的目的。P1指的是由Foo类产生的对象。
能 够推断:假如一个类中定义了一个synchronized的static函数A,也定义了一个synchronized 的instance函数B,那么这个类的同一对象Obj在多线程中分别访问A和B两个方法时,不会构成同步,因为他们的锁都不相同。A方法的锁是Obj所 属的那个Class,而B的锁是Obj所属的这个对象。
搞清楚synchronized锁定的是哪个对象,就能帮助我们设计更安全的多线程程序。
分享到:
相关推荐
java高并发开发必须要会的知识,锁知识,关键字 Synchronized_锁升级知识点总结,面试常用
相信很多小伙伴对于CAS,Synchronized相关的问题都很纠结,包括UP也是,对于这几个的区别也困扰了很久。那么今天就来做一个总结。 一. CAS 何为CAS。 CAS(Compare And Swap )是乐观锁的一种实现方式,是一种轻量...
synchronized关键字我们大家都知道是线程同步关键字.总结一下日常的使用方法,还有一个坑.
"中兴面试问题总结" 中兴面试问题总结中涉及到多个IT知识点,下面对这些知识点进行总结和详细解释: 1. 多线程之间的调度 在 Java 中,多线程之间的调度是通过 JVM 的调度器来实现的。JVM 的调度器会根据不同的...
JAVA笔试总结 非常全面 基本上囊括了Java所有常考知识点,并且每个知识点都有详细解释。 知识点主要包括: native,transient,volatile,strictfp,CMM,synchronized,java socket,压缩与解压缩,多线程,垃圾回收算法,...
面试题总结——多线程篇 一、多线程实现方式 多线程实现方式主要有四种:继承 Thread 类、实现 Runable 接口、实现 Callable 接口、通过 FutureTask 包装器。这四种方式可以满足不同的需求,例如继承 Thread 类...
内容概要:涵盖各大公司Java后端开发面试的常见考点,例如:Java内存模型、java GC、Synchronized 与Lock锁、java集合、线程池、Spring的IOC等等。帮助你系统复习并掌握核心知识。 适用人群:Java后端开发工程师、...
Lock、Synchronized 和 ReentrantLock 的使用 ...九、总结 Synchronized、ReentrantLock 和 Atomic 都是 Java 中的同步机制,每种机制都有其特点和使用场景。选择哪种机制取决于具体的应用场景和性能要求。
记录了java中常见的一些面试题,synchronized的底层实现机制,nio原理,HashMap工作原理、红黑树原理及构建
Java 集合类面试题总结 Java 集合类是 Java 语言中的一种重要组件,用于存储和操作数据。下面总结了 Java 集合类的一些常见问题和答案。 HashMap 和 Hashtable 的区别 HashMap 和 Hashtable 都是 Java 中的散列表...
看完《think in java》多线程章节,自己写的多线程文档,还结合了其他的相关网络资料。 线程 一....1)为什么要使用线程池 2 2)一个具有线程池的工作队列 3 ...1)ReentrantLock和synchronized关键字的区别 41
一个java的多线程juc总结,其中包含基础知识,现成的状态图,关于synchronized,线程优先级和线程分类,interrupt、interupted、isInterrupted的使用,sleep、yield、join的详细使用,锁和等待池介绍。
Java 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量,相比于synchronized(synchronized通常称为重量级锁),volatile更轻量级,因为它不会引起线程上下文的切换和调度。但是volatile 变量的同步性...
一些关键且实用的Java开发技巧: 基础语法与规范: 始终使用public class并遵循...使用synchronized关键字或Lock接口进行同步控制。 利用ExecutorService进行多线程任务管理。 注意volatile关键字的使用,确保多线程
Java经典面试题总结附带答案 以下是从给定文件中生成的相关知识点: Java基础 1. JDK 和 JRE 的区别是什么?(JDK 是 Java Development Kit,JRE 是 Java Runtime Environment) 2. `==` 和 `equals` 的区别是...
private synchronized void inc(){ j++; System.out.println(Thread.currentThread().getName()+"-inc:"+j); } private synchronized void dec(){ j--; System.out.println(Thread.currentThread().getName()+"-...
此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),...
一. 加载 预加载:1.反射注解框架Reflect信息,在Application内多线程预加载至缓存。...2. 并发操作多用读写锁,少用synchronized,Android虚拟机Art直到Android6.0为止尚未对synchronized做CAS优化,而sy
4.彻底理解synchronized 5.彻底理解volatile 6.你以为你真的了解final吗? 7.三大性质总结:原子性、可见性以及有序性 8.初识Lock与AbstractQueuedSynchronizer(AQS) 9.深入理解AbstractQueuedSynchronizer(AQS) 10....
代码块和静态方法同对象,类锁 对比 对象锁不同对象,类锁 对比 对象锁同对象,类锁 对比 对象锁代码实现SyncDemoSyncThread总结synchronized底层实现原理实现synchronized基础对象在内存中的布局对象头结构Monitor...