知识大全 使用Synchronized块同步变量

Posted 变量

篇首语:五陵年少金市东,银鞍白马渡春风。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 使用Synchronized块同步变量相关的知识,希望对你有一定的参考价值。

Java多线程初学者指南(12):使用Synchronized块同步变量  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  我们可以通过synchronized块来同步特定的静态或非静态方法 要想实现这种需求必须为这些特性的方法定义一个类变量 然后将这些方法的代码用synchronized块括起来 并将这个类变量作为参数传入synchronized块 下面的代码演示了如何同步特定的类方法

        package mythread;          public class SyncThread extends Thread              private static String sync =  ;         private String methodType =  ;              private static void method(String s)                      synchronized (sync)                              sync = s;                 System out println(s);                 while (true);                               public void method ()                      method( method );                  public static void staticMethod ()                      method( staticMethod );                  public void run()                      if (methodType equals( static ))                 staticMethod ();             else if (methodType equals( nonstatic ))                 method ();                  public SyncThread(String methodType)                      thodType = methodType;                  public static void main(String[] args) throws Exception                      SyncThread sample  = new SyncThread( nonstatic );             SyncThread sample  = new SyncThread( static );             sample start();             sample start();              

  运行结果如下

   method staticMethod

  看到上面的运行结果很多读者可能感到惊奇 在上面的代码中method 和staticMethod 方法使用了静态字符串变量sync进行同步 这两个方法只能有一个同时执行 而这两个方法都会执行 行的无限循环语句 因此 输出结果只能是method 和staticMethod 其中之一 但这个程序将这两个字符串都输出了

  出现这种结果的愿意很简单 我们看一下 行就知道了 原来在这一行将sync的值改变了 在这里要说一下Java中的String类型 String类型和Java中其他的复杂类型不同 在使用String型变量时 只要给这个变量赋一次值 Java就会创建个新的String类型的实例 如下面的代码所示

   String s =  hello ;System out println(s hashCode());s =  world ;System out println(s hashCode()); 

  在上面的代码中 第一个s和再次赋值后的s的hashCode的值是不一样的 由于创建String类的实例并不需要使用new 因此 在同步String类型的变量时要注意不要给这个变量赋值 否则会使变量无法同步

  由于在 行已经为sync创建了一个新的实例 假设method 先执行 当method 方法执行了 行的代码后 sync的值就已经不是最初那个值了 而method 方法锁定的仍然是sync变量最初的那个值 而在这时 staticMethod 正好执行到synchronized(sync) 在staticMethod 方法中要锁定的这个sync和method 方法锁定的sync已经不是一个了 因此 这两个方法的同步性已经被破坏了

  解决以上问题的方法当然是将 行去掉 在本例中加上这行 只是为了说明使用类变量来同步方法时如果在synchronized块中将同步变量的值改变 就会破坏方法之间的同步 为了彻底避免这种情况发生 在定义同步变量时可以使用final关键字 如将上面的程序中的 行可改成如下形式

   private final static String sync =  ;

  使用final关键字后 sync只能在定义时为其赋值 并且以后不能再修改 如果在程序的其他地方给sync赋了值 程序就无法编译通过 在Eclipse等开发工具中 会直接在错误的地方给出提示

  我们可以从两个角度来理解synchronized块 如果从类方法的角度来理解 可以通过类变量来同步相应的方法 如果从类变量的角度来理解 可以使用synchronized块来保证某个类变量同时只能被一个方法访问 不管从哪个角度来理解 它们的实质都是一样的 就是利用类变量来获得同步锁 通过同步锁的互斥性来实现同步

cha138/Article/program/Java/gj/201311/27400

相关参考

知识大全 使用Synchronized块同步方法

初学Java多线程:使用Synchronized块同步方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一

知识大全 使用Synchronized关键字同步类方法

初学Java多线程:使用Synchronized关键字同步类方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起

知识大全 使用Synchronized关键字同步类方法

Java多线程初学者指南(10):使用Synchronized关键字同步类方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,

知识大全 java多线程中synchronized关键字的用法

  由于同一进程内的多个线程共享内存空间在Java中就是共享实例当多个线程试图同时修改某个实例的内容时就会造成冲突因此线程必须实现共享互斥使多线程同步  最简单的同步是将一个方法标记为synchron

知识大全 java的volatile与多线程

  Java语言规范中指出为了获得最佳速度允许线程保存共享成员变量的私有拷贝而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比  Volatile修饰的成员变量在每次被线程访问时都强迫从

知识大全 Java 理论与实践: 正确使用 volatile 变量 线程同步

Java理论与实践:正确使用volatile变量线程同步  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下

知识大全 Java中对线程间的变量访问也需要同步控制

Java中对线程间的变量访问也需要同步控制  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  一个简

知识大全 线程的同步-同步块

Java线程:线程的同步-同步块  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &nbs

知识大全 Java多线程Synchronized的注意细节

Java多线程Synchronized的注意细节  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 使用synchronized和Lock对象获取对象锁

使用synchronized和Lock对象获取对象锁  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!