2013-02-19 62 views
1

而且請不要陷入這樣一個想法:你可以鎖定一個類A的任意實例,並以某種方式鎖定另一個類A的實例。這是一個經典的初學者的錯誤。Java中同步語句的靜態鎖對象

在我明白之前,我犯過幾次錯誤。但是靜態鎖定對象正常工作。

MyThread的

package com.replanet; 

public class MyThread extends Thread { 

    private int x, y; 
    private static Object lock3 = new Object(); 

    public MyThread(int x, int y) { 
     this.x = x; 
     this.y = y; 
    } 

    @Override 
    public void run() { 
     super.run(); 
     try { 
      test_Method(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

    } 

    private void test_Method() throws InterruptedException { 
     synchronized (lock3) { 
      System.out.println("test_Method " + Thread.currentThread().getName()); 
      for (int i = 0; i < Integer.MAX_VALUE; i++) { 
       if (i == Integer.MAX_VALUE/2) { 
        Thread.sleep(2000); 
        System.out 
          .println("Leaving test_Method on " + Thread.currentThread().getName()); 
        return; 
       } 
      } 
     } 
    } 

} 

用法

package com.replanet; 

public class Main { 

    public static void main(String[] args) { 

     MyThread myThread1 = new MyThread(1, 2); 
     MyThread myThread2 = new MyThread(1, 2); 
     myThread1.start(); 
     myThread2.start(); 
    } 
} 

輸出

test_Method Thread-0 
Leaving test_Method on Thread-0 
test_Method Thread-1 
Leaving test_Method on Thread-1 

輸出非靜態鎖定對象(不適合我)

test_Method Thread-0 
test_Method Thread-1 
Leaving test_Method on Thread-1 
Leaving test_Method on Thread-0 

是否使用static鎖定對象是個好主意?

+2

對於我來說,擁有一個靜態對象和兩個線程來修改它並沒有什麼意義,爲什麼不在單個線程中完成這項工作呢? – 2013-02-19 09:39:10

+0

@BobFlannigon,我發佈的代碼是來自我的真實應用程序的一段非常簡單的代碼。我有很多線程同時工作,必須照顧一部分代碼,並允許唯一的一個線程輸入它。 – 2013-02-19 09:40:55

回答

3

您可以在Class自己鎖定 - 這更有意義和更容易閱讀:

private void test_Method() throws InterruptedException { 
     synchronized (MyThread.class) { 
      System.out.println("test_Method " + Thread.currentThread().getName()); 
      for (int i = 0; i < Integer.MAX_VALUE; i++) { 
       if (i == Integer.MAX_VALUE/2) { 
        Thread.sleep(2000); 
        System.out 
          .println("Leaving test_Method in " + Thread.currentThread().getName()); 
        return; 
       } 
      } 
     } 
    } 

或者,如果你不需要的方法是一個實例方法:

private static synchronized void test_Method() throws InterruptedException { 
      System.out.println("test_Method " + Thread.currentThread().getName()); 
      for (int i = 0; i < Integer.MAX_VALUE; i++) { 
       if (i == Integer.MAX_VALUE/2) { 
        Thread.sleep(2000); 
        System.out 
          .println("Leaving test_Method in " + Thread.currentThread().getName()); 
        return; 
       } 
      } 
    } 

您可能還需要閱讀新的(ish)Lock課程。

+0

'MyThread.class'適合我。謝謝! – 2013-02-19 09:45:28

1

而不是靜態讓MyThread共享一個鎖對象會更好。更面向對象。

0

無論是靜態或實例成員取決於你希望它有範圍的,但什麼絕對一個很好的做法是有一個私人對象鎖定。這是鎖定(顯然是公共的)類對象的主要優點。