黑马程序员技术交流社区

标题: 静态变量同步的问题 [打印本页]

作者: 吴璞玉    时间: 2012-3-13 18:02
标题: 静态变量同步的问题
在类中给2个以上的静态方法加synchronized时,那么线程会不会同时进入这2个静态方法?线程如果同时执行类中的非静态方法,如果这个时候类中的非静态方法修改了静态变量的值,那静态变量的同步岂不是失败了么
作者: 张锐    时间: 2012-3-13 21:21
写了个例子验证了一下:
  1. package test;

  2. import myutil.SOP;

  3. public class TestSynchronized2 {

  4.         /**
  5.          * @param args
  6.          * @throws InterruptedException
  7.          */
  8.         public static void main(String[] args) throws InterruptedException {
  9.                 // TODO Auto-generated method stub
  10.                 MySync2 ms1 = new MySync2();
  11.                 ms1.setFlag(1);
  12.                 MySync2 ms2 = new MySync2();
  13.                 ms2.setFlag(2);
  14.                 MySync2 ms3 = new MySync2();
  15.                 ms3.setFlag(3);
  16.                
  17.                 Thread t1 = new Thread(ms1);
  18.                 Thread t2 = new Thread(ms2);
  19.                 Thread t3 = new Thread(ms3);
  20.                 t1.start();
  21.                 Thread.sleep(100);
  22.                 t2.start();
  23.                 t3.start();
  24.         }

  25. }

  26. class MySync2 implements Runnable{
  27.         private int flag = 0;
  28.         private static int i = 0;
  29.        
  30.         public void setFlag(int flag) {
  31.                 this.flag = flag;
  32.         }
  33.        
  34.         static synchronized void method1() throws InterruptedException{
  35.                 i=10;
  36.                 Thread.sleep(5000);
  37.                 SOP.sop("method1---"+i);
  38.         }
  39.         static synchronized void method2() throws InterruptedException{
  40.                 i=20;
  41.                 Thread.sleep(2000);
  42.                 SOP.sop("method2---"+i);
  43.         }
  44.         void method3() throws InterruptedException{
  45.                 i = 1000;
  46.                 SOP.sop("method3---"+i);
  47.         }
  48.         @Override
  49.         public void run() {
  50.                 switch (flag) {
  51.                 case 1:
  52.                         try {
  53.                                 method1();
  54.                         } catch (InterruptedException e) {
  55.                                 // TODO Auto-generated catch block
  56.                                 e.printStackTrace();
  57.                         }
  58.                         break;
  59.                 case 2:
  60.                         try {
  61.                                 method2();
  62.                         } catch (InterruptedException e) {
  63.                                 // TODO Auto-generated catch block
  64.                                 e.printStackTrace();
  65.                         }
  66.                         break;
  67.                 case 3:
  68.                         try {
  69.                                 method3();
  70.                         } catch (InterruptedException e) {
  71.                                 // TODO Auto-generated catch block
  72.                                 e.printStackTrace();
  73.                         }
  74.                         break;

  75.                 default:
  76.                         SOP.sop("here is default");
  77.                         break;
  78.                 }
  79.                 // TODO Auto-generated method stub
  80.                
  81.         }
  82. }
复制代码
结果是:
method3---1000
method1---1000
method2---20

得出的结论是:
静态方法的默认的锁是类本身,所以两个静态的方法是不可能同时被调用的,只有一前一后的顺序。但是非静态方法就不一定了。
上面这个例子的情况是:
t1先把 i 改成10,然后锁上,这时候t2不可以进来了,但是因为t3不受锁的限制,进来把 i 改成1000 并且输出,后来t1醒来后,i 已经变成1000了,所以输出1000,t1释放所后,t2再进来,把 i 改成20,然后输出20.
   




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2