`
yunshangbuhe
  • 浏览: 228921 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

synchronized 使用

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

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

Java的synchronized使用方法总结

1.  把synchronized当作函数修饰符时,示例代码如下:

Public synchronized void method(){   //….   }  
这也就是同步方法,那这时synchronized锁定的是哪个对象呢?他锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中执行这个同步方法时,他们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却能够任意调用这个被加了synchronized关键字的方法。
上边的示例代码等同于如下代码:

public void method()   {   synchronized (this)      //  (1)   {          //…..   }   } 
  (1)处的this指的是什么呢?他指的就是调用这个方法的对象,如P1。可见同步方法实质是将synchronized作用于object reference。――那个拿到了P1对象锁的线程,才能够调用P1的同步方法,而对P2而言,P1这个锁和他毫不相干,程式也可能在这种情形下摆脱同步机制的控制,造成数据混乱。

2.同步块,示例代码如下:

public void method(SomeObject so) {   synchronized(so)   {          //…..   }   }  
这时,锁就是so这个对象,谁拿到这个锁谁就能够运行他所控制的那段代码。当有一个明确的对象作为锁时,就能够这样写程式,但当没有明确的对象作为锁,只是想让一段代码同步时,能够创建一个特别的instance变量(他得是个对象)来充当锁:

class Foo implements Runnable   {          private byte[] lock = new byte[0];  // 特别的instance变量       Public void method()   {          synchronized(lock) { //… }   }   //…..   }  
注:零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码。

3.将synchronized作用于static 函数,示例代码如下:

     
Class Foo   {   public synchronized static void method1()   // 同步的static 函数   {   //….   }   public void method2()   {          synchronized(Foo.class)   //  class literal(类名称字面常量)   }          }   
代码中的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的博客。

分享到:
评论

相关推荐

    Java synchronized使用案例

    在`Synchronized`压缩包中,可能包含了通过实验来演示`synchronized`关键字使用的一些Java代码。例如,创建一个共享资源类,然后通过多个线程去操作这个资源,使用`synchronized`关键字来保证线程安全。实验可能涉及...

    17 资源有限,请排队等候—Synchronized使用、原理及缺陷.pdf

    本章重点讲述了`synchronized`的使用、工作原理及其潜在的缺陷。 首先,`synchronized`的主要作用在于保证线程同步,即在多线程环境下,对共享资源的访问进行控制,确保同一时刻只有一个线程能够访问特定的代码块或...

    解决Maven 项目报错 java.httpservlet和synchronized使用方法

    解决Maven项目报错java.httpservlet和synchronized使用方法 在Maven项目中,我们经常会遇到一些报错问题,例如java.httpservlet和synchronized使用方法等。这篇文章将为大家带来解决Maven项目报错java.httpservlet...

    synchronized用法大全实例

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

    java中synchronized的使用

    java中synchronized的使用,java中的锁锁的到底是什么?是括号里的代码块吗?肯定不是的;

    [JAVA][synchronized的使用]

    本篇文章将深入探讨`synchronized`的使用,包括其基本原理、使用方式以及实际应用场景。 1. **synchronized的基本原理** `synchronized`关键字在Java中提供了互斥访问,也就是说,当一个线程进入一个对象的`...

    java锁机制Synchronizedjava锁机制Synchronized

    但是,在某些情况下,可能需要在一定时期内霸占某个对象的钥匙,这时可以使用 Synchronized 代码块。 Java 锁机制 Synchronized 的优点 Java 锁机制 Synchronized 的优点是可以解决多线程并发访问共享资源时可能...

    java里面synchronized用法.doc

    Java 中的 synchronized 用法详解 Java 中的 synchronized 关键字是用于解决多线程并发问题的重要工具之一。...正确地使用 synchronized 关键字可以帮助开发者们编写更加高效、可靠的多线程程序。

    Android synchronized 测试案例

    本测试案例深入探讨了`synchronized`的使用方法,包括同步单个对象、同步多个对象以及成功与失败的场景对比。 一、`synchronized`关键字的基本概念 `synchronized`关键字可以修饰方法或用作代码块,其主要作用是...

    java中synchronized用法

    "Java 中 synchronized 用法详解" Synchronized 是 Java 语言中用于解决多线程共享数据...synchronized 关键字是 Java 语言中解决多线程共享数据同步问题的重要工具,但需要正确地使用它,以免造成死锁和系统开销。

    Java中使用synchronized关键字实现简单同步操作示例

    下面将详细介绍`synchronized`关键字的三种使用方式:修饰函数、修饰代码块以及修饰静态方法。 1. **synchronized 修饰函数** 当`synchronized`修饰非静态方法时,它会锁定当前对象实例。这意味着,对于同一个对象...

    volatile和synchronized的区别

    5. **线程阻塞**:使用`synchronized`时,当一个线程持有锁时,其他试图获取该锁的线程会被阻塞;而使用`volatile`时,不会发生线程阻塞。 #### 四、使用建议 - 对于简单的状态变量(如标志位)的可见性保证,推荐...

    synchronized关键字的用法详解

    `synchronized`关键字有两种主要的使用方式:一种是在方法声明中使用,另一种则是在代码块中使用。 ##### 1. synchronized方法 在方法声明中添加`synchronized`关键字,可以将整个方法体变成同步代码块。例如: `...

    synchronized并发讲解源码.zip

    本文将深入解析`synchronized`的工作原理、使用方式以及它在并发编程中的重要性。通过分析提供的源码,我们可以更直观地理解这个关键字的实际应用。 `synchronized`关键字主要有两种用法:修饰实例方法和同步代码块...

    synchronized的几种示例

    本文将深入探讨`synchronized`的几种使用示例,包括方法加锁、代码块加锁(针对`this`和对象)以及静态方法加锁。 1. **方法加锁** 当在实例方法前使用`synchronized`关键字时,它会锁定当前对象的监视器,只有...

    synchronized关键字的实质及用法

    1. **synchronized的两种使用方式** - **方法同步**:在方法声明前加上`synchronized`关键字,这将使得整个方法成为同步方法,每次只有一个线程可以执行该方法。 ```java public synchronized void someMethod...

    Synchronized关键字的用法

    - **非阻塞算法**:为了减少锁的竞争,可以考虑使用非阻塞算法或工具类如`java.util.concurrent`包下的类来替代`synchronized`。 #### 结论 `synchronized`关键字是Java中实现线程安全的基础工具之一,通过对共享...

    正确使用多线程同步锁@synchronized()1

    本文将深入探讨`@synchronized`的工作原理、特点以及使用时需要注意的事项。 首先,`@synchronized`的原理是基于递归互斥锁(Recursive Mutex)。在Objective-C中,当你使用`@synchronized`块包围一段代码时,会为...

    JAVA synchronized详解

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

    java_synchronized详解

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

Global site tag (gtag.js) - Google Analytics