2012-07-18 212 views
0
public class Common {  
    public synchronized void synchronizedMethod1() { 
     System.out.println("synchronizedMethod1 called"); 
     try { 
      Thread.sleep(1000); 
      } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.out.println("synchronizedMethod1 done"); 
    } 
    public void method1() { 
     System.out.println("Method 1 called"); 
     try { 
      Thread.sleep(1000); 
      } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.out.println("Method 1 done"); 
    } 
} 



public class MyThread extends Thread { 
    private int id = 0; 
    private Common common; 

    public MyThread(String name, int no, Common object) { 
     super(name); 
     common = object; 
     id = no; 
    } 

    public void run() { 
     System.out.println("Running Thread" + this.getName()); 
     try { 
      if (id == 0) { 
       common.synchronizedMethod1(); 
       } else { 
       common.method1(); 
      } 
      } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 
     Common c = new Common(); 
     MyThread t1 = new MyThread("MyThread-1", 0, c); 
     MyThread t2 = new MyThread("MyThread-2", 1, c); 
     t1.start(); 
     t2.start(); 
    } 
} 

輸出:線程調用非同步實例方法時的同步方法被調用

Running ThreadMyThread-1 
synchronizedMethod1 called 
Running ThreadMyThread-2 
Method 1 called 
synchronizedMethod1 done 
Method 1 done 

我想找到一種方法,以防止運行時,我叫synchronizedMethod1方法1()。除非我誤認爲所有的方法都被調用,並且Java在運行時和運行之前編譯它們,而不管它是否同步。

我應該使用一個Lock對象來替代和/或不要使method1()是一個同步方法嗎?

+0

您應該在發佈時設置您的代碼的格式,這樣可以更容易閱讀。 – 2012-07-18 20:08:42

+0

thx編輯獵人! – bouncingHippo 2012-07-18 20:10:01

回答

0

如果你想要method1synchronizedMethod1是互斥的,那麼你需要用相同的鎖來保護它們。無論這是使用Lock還是僅在同一對象實例上調用synchronize,結果大致相同。

如果您希望允許多個線程執行method1而不是synchronizedMethod1正在被調用,那麼您需要一個ReadWriteLock來完成該任務。

public class Common {  
    ReadWriteLock rwLock = new ReentrantReadWriteLock(); 

    public void synchronizedMethod1() { 
     rwLock.writeLock().lock(); 
     try { 
      System.out.println("synchronizedMethod1 called"); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      System.out.println("synchronizedMethod1 done"); 
     } finally { 
      rwLock.writeLock().unlock(); 
     } 
    } 
    public void method1() { 
     rwLock.readLock().lock(); 
     try { 
      System.out.println("Method 1 called"); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      System.out.println("Method 1 done"); 
     } finally { 
      rwLock.readLock().unlock(); 
     } 
    } 
} 
1

我想找到一種方法來防止方法1()運行時,我叫synchronizedMethod1

做到這一點,最簡單的方法是讓method1()也​​。這將意味着這兩種方法都會導致他們正在調用的Common實例的鎖定。只有一個線程可以呼叫synchronizedMethod1()method1()

除非我誤以爲所有方法都被調用,並且Java在運行期間和運行前編譯它們,無論它是否同步。

我不明白這個問題。您真的不必擔心JVM的編譯或優化階段。

我應該使用Lock對象嗎?

通常使方法​​被認爲不如使用private final鎖對象。鎖對象只是讓你在你的鎖中更加細緻。例如,通過方法鎖定,日誌消息和其他不需要保護的語句也將爲​​。但如果目標是鎖定整個方法,那麼同步方法就沒有問題。

相關問題