`

synchronized 在线程安全中用法

阅读更多

synchronized 相当于锁机制,保证代码块的互斥访问,保证线程安全。

synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。

注意:

    A.无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。
   B.每个对象只有一个锁(lock)与之相关联。
   C.实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,因此在实时性要求高的并发编程中,尽量避免无谓的同步控制。

用法主要是:

  一:锁住方法; 

 

public synchronized void method() {
。。。
}
 

       它锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中执行这个同步方法时,它们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却可以任意调用这个被加了synchronized关键字的方法。

   上面的代码等同于:

  public void method(){

 
  synchronized(this){
   ...
       }
}

   this指的就是调用这个方法的对象,如P1。同步方法实质是将synchronized作用于object reference。――那个拿到了P1对象锁的线程,才可以调用P1的同步方法,而对P2而言,P1这个锁与它毫不相干,程序也可能在这种情形下摆脱同步机制的控制,造成数据混乱。
二:锁住代码块: 

 

 public void method(Object ob)
 {
     synchronized (ob){。。。} 
 }

        这时,锁就是ob这个对象,谁拿到这个锁谁就可以运行它所控制的那段代码。当有一个明确的对象作为锁时,就可以这样写程序,但当没有明确的对象作为锁,只是想让一段代码同步时,可以创建一个特殊的instance变量(它得是一个对象)来充当锁:

class Foo implements Runnable
{
       private byte[] lock = new byte[0];  // 特殊的instance变量
    Public void methodA()
{
       synchronized(lock) { … }
}
 
  public void run(){
   ...
   }
}
 

     注:零长度的byte数组对象创建起来将比任何对象都经济,查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码。

三:synchronized作用于static函数:

     Class Foo
    {
      public synchronized static void methodA()   // 同步的static 函数
       {
          ….
       }
        public void methodB()
    {
       synchronized(Foo.class)   //  class literal(类名称字面常量)
     }
       }

    这两个同步方法产生的效果是一样的,取得的锁是当前调用这个方法的对象所属的类(Class,而不再是由这个Class产生的某个具体对象了)。

    注意:

     Foo.class和 P1.getClass()用于作同步锁还不一样,不能用P1.getClass()来达到锁这个Class的目的。 P1指的是由Foo类产生的对象。

     如果一个类中定义了一个synchronized的static函数A,也定义了一个synchronized 的instance函数B,那么这个类的同一对象Obj在多线程中分别访问A和B两个方法时,不会构成同步,因为它们的锁都不一样。A方法的锁是Obj这个对象,而B的锁是Obj所属的那个Class。也就是说静态方法属于类的范畴,实例方法属于对象的范畴,范畴的不一样导致同步时取锁的范畴也不一样。搞清楚synchronized锁定的是哪个对象,才能设计更安全的多线程程序。

 

四:还有一些技巧可以让我们对共享资源的同步访问更加安全:

   1. 定义实例变量(instance变量)时为private类型,并且通过get()方法获取这个私有变量,这样就可以防止直接修改这个变量。javabean就是应用到这种机制。

  2. 当这个变量为对象时,比如数组和一些链表容器:ArrayList等,由于通过get()方法同样能得到这个变量的引用,并且将这个变量赋值给另外的对象引用而修改这个对象引用,所以需要在这个get()方法上加上synchronized方法,并且返回这个private对象的clone(),也就是一份副本拷贝,而不是对象应用本身,这样会更安全。

 

分享到:
评论

相关推荐

    synchronized与单例的线程安全

    3. 懒汉式(线程安全):在多线程环境中,使用`synchronized`保证实例化过程的线程安全,但可能导致性能下降。 ```java public class Singleton { private static Singleton INSTANCE; private Singleton() {} ...

    java多线程中synchronized关键字的用法

    java多线程中synchronized关键字的用法 解压密码 www.jiangyea.com

    servlet线程安全问题

    Servlet 线程安全问题是指在使用 Servlet 编程时,如果不注意多线程安全性问题,可能会导致难以发现的错误。Servlet/JSP 技术由于其多线程运行而具有很高的执行效率,但这也意味着需要非常细致地考虑多线程的安全性...

    关于如何解决HashMap线程安全问题的介绍

    无论是使用Collections.synchronizedMap()、ConcurrentHashMap还是避免在多线程环境中使用,都需要根据应用的具体场景来权衡性能与安全。在设计和编写多线程程序时,要始终关注数据结构的选择和操作的同步控制,以...

    【ASP.NET编程知识】实例解析Java中的synchronized关键字与线程安全问题.docx

    在Java编程中,`synchronized`关键字是用来解决多线程环境下的线程安全问题的关键工具。线程安全意味着当多个线程访问同一段代码时,该代码能够正确地处理并发情况,不会出现数据不一致或者资源竞争的问题。本文将...

    java中synchronized用法

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

    Java非线程安全类变线程安全类.pdf

    该类使用 synchronized 关键字来同步 setState 方法,以确保在同一个时间点只有一个线程可以执行该方法,从而避免了线程安全问题。 Java 中的非线程安全类可以通过使用 ThreadLocal 或 synchronized 关键字来实现...

    servlet与Struts action线程安全问题分析

    在上述例子中,`ConcurrentTest`Servlet定义了一个实例变量`output`,在`service`方法中,这个变量被用来向客户端响应。当多个线程同时访问`service`方法,可能会出现线程A处理的用户信息被线程B误写入到响应中,...

    java 多线程synchronized互斥锁demo

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

    java线程安全测试

    在Java中,线程安全问题通常与并发、内存模型和可见性有关。Java内存模型(JMM)定义了如何在多线程环境下共享数据的规则,确保线程之间的正确交互。 线程安全可以分为三种类型: 1. 不安全:当多个线程访问共享...

    Java多线程安全集合

    线程安全是指一个类或者方法在多线程环境中被调用时,能够正确地处理并发访问,不会因为线程间的交互而产生错误或不确定的行为。在Java中,线程安全的集合主要分为三类:同步集合、并发集合和不可变集合。 1. 同步...

    线程安全测试类

    在Java编程语言中,线程安全是多线程环境下程序正确性和稳定性的重要概念。线程安全测试类的设计是为了确保在并发环境中,多个线程访问共享资源时不会导致数据的不一致或异常行为。本测试主要关注`synchronized`...

    局部变量线程安全测试

    在编程领域,线程安全是多线程编程中的一个重要概念,尤其在Java、C++等支持并发编程的语言中。线程安全通常指的是当多个线程访问一个对象时,如果对象的状态始终保持一致,那么我们就说这个对象是线程安全的。这里...

    java同步synchronized关键字用法示例

    Java中的`synchronized`...总之,`synchronized`关键字在Java多线程编程中扮演着关键角色,确保了共享资源的安全访问,避免了竞态条件和数据不一致。理解和熟练运用`synchronized`对于编写健壮的并发程序至关重要。

    synchronized关键字的实质及用法

    在Java编程语言中,`synchronized`关键字是用于实现线程同步的重要工具,它的本质在于确保多线程环境下的数据一致性与安全性。通过`synchronized`,我们可以控制对共享资源的访问,避免并发问题,如数据竞争和死锁。...

    Action是否线程安全

    设计线程安全的`Action`时,你需要确保所有的方法都具有适当的同步机制,如`synchronized`关键字,或者使用`java.util.concurrent`包中的工具,如`ExecutorService`、`Semaphore`等。 2. **`javax.swing....

    java里面synchronized用法.doc

    在上面的例子中,synchronized 关键字被用于静态方法 myStaticMethod 上,以防止多个线程同时访问同一个类中的静态方法。 二、synchronized 关键字的使用 除了被用于方法上,synchronized 关键字也可以被用于代码...

    synchronized关键字的用法详解

    在这个示例中,`Thread1`类实现了`Runnable`接口,并在`run`方法中定义了一个`synchronized(this)`代码块。当两个线程`A`和`B`分别启动时,它们都将尝试执行该同步代码块。根据`synchronized`的特性,一次只有一个...

    java线程安全总结.doc

    Java线程安全是多线程编程中的一个关键概念,它涉及到在并发环境下如何正确地管理共享资源,确保程序的正确性和一致性。以下是对Java线程安全的深入总结: ### 一、线程安全的定义 线程安全是指当多个线程访问同一...

Global site tag (gtag.js) - Google Analytics