类的静态方法之间的同步

时间:2011-01-28 05:03:42

标签: java multithreading synchronization locking static-methods

我写了以下代码:

public class ClassAndObjectLock {
 public static void main(String[] args) {
  new Thread(new EvenThread()).start();
  new Thread(new OddThread()).start();
 }
}

class EvenThread implements Runnable {
 public void run() {
  for (int i = 0; i < 10; i += 2) {
   CommonClass.printEvenNumber(i);
  }
 }
}

class OddThread implements Runnable {
 public void run() {
  for (int i = 1; i < 10; i += 2) {
   CommonClass.printOddNumber(i);
  }
 }
}

class CommonClass {
 public static void printEvenNumber(int num) {
  synchronized (CommonClass.class) {
   System.out.println("Even :" + num);
  }
 }

 public static void printOddNumber(int num) {
  synchronized (CommonClass.class) {
   System.out.println("Odd :" + num);
  }
 }
}

当我执行上面的代码时,输​​出如下:

Even :0
Odd :1
Even :2
Odd :3
Even :4
Odd :5
Even :6
Odd :7
Even :8
Odd :9

我不明白这个输出。根据我的理解,当new Thread(new EvenThread()).start();被执行时,它会生成一个类EvenThread的线程,该线程应获取CommonClass的锁并保持锁定,直到它打印出全部偶数值。 OddThread的对象只有在EvenThread的对象完成后才有机会。因此,在我看来,输出应该如下:

Even :0  
Even :2
Even :4
Even :6
Even :8
Odd :1
Odd :3
Odd :5
Odd :7
Odd :9

有人可以解释我的基本逻辑吗?

2 个答案:

答案 0 :(得分:2)

  

根据我的理解,当新的Thread(new EvenThread())。start();执行后,它会生成一个类EvenThread的线程,该线程应该获取CommonClass的锁并保持锁定,直到它打印出全部偶数值。

不,事实并非如此:

 public static void printOddNumber(int num) {
   synchronized (CommonClass.class) {
       System.out.println("Odd :" + num);
   }
 }

其中(由于该方法在监控类上是静态的),也可以写为

 public static synchronized void printOddNumber(int num) {
       System.out.println("Odd :" + num);
 }

查看synchronized块的范围:它打印只有一个数字,然后释放锁。

如果你想打印所有数字而不被打断,你必须锁定整个for循环的持续时间:

public void run() {
  synchronized(CommonClass.class){
    for (int i = 0; i < 10; i += 2) {
     System.out.println("Even :" + num);
    }
  }
}

答案 1 :(得分:1)

您的同步处于打印方法的级别,这意味着每个打印都会获取并释放锁定。如果您希望线程在持续时间内保持锁定,则必须在线程的run方法中同步该对象(在循环周围)。

相关问题