`

(转)Java的synchronized使用方法总结

阅读更多

源地址: http://www.qqread.com/java/2009/08/w472329.html

 

不久前用到了同步,现在回过头来对JAVA中的同步做个总结,以对前段时间工作的总结和自我技术的条理话。JAVA的synchronized关键字能够作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。假如再细的分类,synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。
在进一步阐述之前,我们需要明确几点:
A.无论synchronized关键字加在方法上还是对象上,他取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。
B.每个对象只有一个锁(lock)和之相关联。
C.实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。
接着来讨论synchronized用到不同地方对代码产生的影响:

假设P1、P2是同一个类的不同对象,这个类中定义了以下几种情况的同步块或同步方法,P1、P2就都能够调用他们。

Java的synchronized使用方法总结

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所属的这个对象。

Java的synchronized使用方法小结如下:

搞清楚synchronized锁定的是哪个对象,就能帮助我们设计更安全的多线程程式。

更有一些技巧能够让我们对共享资源的同步访问更加安全:
1.  定义private 的instance变量+他的 get方法,而不要定义public/protected的instance变量。假如将变量定义为public,对象在外界能够绕过同步方法的控制而直接取得他,并改变他。这也是JavaBean的标准实现方式之一。
2.  假如instance变量是个对象,如数组或ArrayList什么的,那上述方法仍然不安全,因为当外界对象通过get方法拿到这个instance对象的引用后,又将其指向另一个对象,那么这个private变量也就变了,岂不是很危险。 这个时候就需要将get方法也加上synchronized同步,并且,只返回这个private对象的clone()――这样,调用端得到的就是对象副本的引用了。

本文来自leo_faith的博客。

扩展阅读:125条常见的java面试笔试题大汇总

lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。当你知道字符数据要改变的时候你就可以使用StringBuffer。它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类)。

分享到:
评论

相关推荐

    java synchronized demo

    在Java编程语言中,`...总结,`java synchronized demo`是一个关于如何在Java中使用`synchronized`关键字进行线程同步的示例,通过理解和实践这个例子,开发者可以更好地掌握多线程环境下数据安全和同步的重要性。

    [JAVA][synchronized的使用]

    总结,`synchronized`是Java中实现线程安全的关键工具,理解其工作原理和使用方式对于编写高效、安全的多线程程序至关重要。然而,在实际应用中,我们需要根据具体场景选择最合适的并发控制手段,平衡性能和安全性。

    Java使用synchronized修饰方法来同步线程的实例演示

    本文将深入探讨synchronized修饰方法在Java中的使用及其工作原理,并通过实例演示其应用。 1. **synchronized原理** synchronized基于Java的内置锁(也称为对象锁或 monitors)机制。当一个线程进入synchronized...

    Java synchronized关键_动力节点Java学院整理

    1. **对象锁**:每个Java对象都可以作为一个锁,当调用对象的`synchronized`方法或在代码块中使用`synchronized`关键字时,会获取到这个对象的锁。如果多个线程尝试访问同一个对象的同步代码,只有一个线程能够获得...

    java_synchronized详解

    通过在方法或代码块上使用`synchronized`,可以确保同一时间只有一个线程能访问这些代码区域,从而有效避免了多线程环境下的数据竞争和不一致性问题。 #### 二、synchronized的作用机制 `synchronized`主要通过对象...

    synchronized用法大全实例

    本实例大全将全面解析`synchronized`的使用方式,包括同步方法、同步语句块、类锁和对象锁。 ### 1. 同步方法 同步方法是通过在方法声明前加上`synchronized`关键字实现的。这样,同一时间只有一个线程可以执行该...

    java synchronized详解

    Java中的`synchronized`关键字是多线程...总结,`synchronized`是Java多线程编程中不可或缺的一部分,它通过锁机制保证了共享资源的线程安全。了解并熟练掌握`synchronized`的使用,有助于编写出高效且正确的并发程序。

    JAVA synchronized详解

    通过使用`synchronized`,可以确保同一时刻只有一个线程能够访问被标记为同步的方法或代码块,从而避免多线程环境下的数据不一致问题。 #### 一、基本概念 `synchronized`关键字主要具有以下特性: 1. **互斥性**...

    Java-synchronized详解.docx

    当一个线程调用 synchronized 方法时,Java 虚拟机(JVM)会检查该方法是否被锁定,如果该方法已经被锁定,其他线程无法访问该方法,直到锁被释放。这种机制可以确保在同一时间只有一个线程可以访问该方法,以避免...

    java-synchronized详解.doc

    总结来说,`synchronized`是Java中实现线程同步的关键机制,确保了多线程环境下的数据一致性。理解它的用法和工作原理对于编写健壮的多线程程序至关重要。正确使用`synchronized`可以帮助开发者避免竞态条件和死锁等...

    java基本教程之synchronized关键字java多

    总结,`synchronized`关键字是Java多线程编程中的关键工具,理解并合理运用它,可以帮助开发者编写出高效且线程安全的代码,避免数据竞争和死锁等问题。通过深入学习和实践,可以提升Java程序员在并发编程领域的专业...

    Java Synchronized的使用详解

    下面是对Java Synchronized的使用详解的知识点总结: 1. 为什么要使用Synchronized? 在并发编程中,存在线程安全问题的主要原因是共享数据和多线程共同操作共享数据。使用Synchronized可以解决这个问题,确保在...

    java 多线程synchronized互斥锁demo

    标题中的"java 多线程synchronized互斥锁demo"指的是一个示例,展示了如何在多线程环境下使用`synchronized`关键字创建互斥锁,确保同一时间只有一个线程可以访问特定的代码块或方法。 描述中的"一个多线程访问的同...

    java-synchronized 嵌套使用代码详解

    总结来说,java-synchronized 嵌套使用代码详解是 Java 编程语言中的一种同步机制,但是如果使用不当,可能会导致死锁的发生。因此,在编写多线程程序时,需要小心地使用 synchronized,避免死锁的发生。 知识点: ...

    深入理解java中的synchronized关键字

    总结来说,`synchronized`关键字在Java中扮演着至关重要的角色,它是保证多线程环境下数据一致性的重要工具。通过合理使用synchronized方法和synchronized块,开发者可以有效地控制并发访问,防止数据竞争问题,确保...

    java synchronized关键字原理、自定义一把锁来实现同步等

    ### Java synchronized 关键字原理与自定义锁实现详解 #### 一、Java synchronized 关键字原理 `synchronized` 是 Java 中的关键字之一,用于实现线程间的同步控制,确保共享资源的安全访问。它主要应用于以下两种...

    Java synchronized那点事.doc

    总结来说,Java synchronized机制是通过锁的状态管理来实现线程同步,包括从无锁到偏向锁、轻量级锁再到重量级锁的逐步升级。这些状态转换是根据并发情况动态调整的,以平衡性能和同步需求。理解这些机制有助于优化...

    Java并发编程系列- synchronized

    总结来说,`synchronized`在Java并发编程中扮演着核心角色,它通过锁机制确保了共享资源的安全访问,解决了多线程环境下的数据一致性问题。正确理解和使用`synchronized`对于编写高效、线程安全的Java代码至关重要。

    java知识体系总结

    Java知识体系总结 Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems(现已被Oracle公司收购)于1995年推出。它以其“一次编写,到处运行”的特性闻名,适用于开发跨平台的应用程序,包括桌面应用、企业...

Global site tag (gtag.js) - Google Analytics