2012-10-15 103 views

回答

0

他們並非互爲多變的,因爲他們鎖定不同的對象。

如果鎖定對象是合適的,請使用它。如果你想鎖定一個類(這不太可能),你會使用它。

我會考慮這個組合。

public void log2(String msg1, String msg2){ 
    synchronized(this) { 
     synchronized(log) { 
      log.writeln(msg1); 
      log.writeln(msg2); 
     } 
    } 
} 

這將確保對象沒有被修改,並且行在日誌中一起出現。

但是由於LOG2似乎沒有使用可變字段,你可以使用

private final Log log = ... 

public void log2(String msg1, String msg2){ 
    synchronized(log) { 
     log.writeln(msg1); 
     log.writeln(msg2); 
    } 
} 
1

如果在類中創建一個鎖,那麼該類的所有實例將共享鎖。如果您有1個實例,則不會有任何區別。如果您有數千個實例,則它們將全部使用相同的鎖。如果許多線程試圖同時獲取鎖,它們將互相阻塞。在最糟糕的情況下,這可能會導致您的代碼表現得好像根本沒有線程。

如果你在實例上創建了鎖,那麼只要它們在不同的實例上運行,幾個線程就可以執行受保護的代碼。在這裏,線程不會彼此阻塞。所以這種方法表現更好。

但這不是你需要問的。真正的問題是:我需要什麼樣的鎖?

如果您想確保只有一個線程可以寫入日誌,您應該同步log。這種方法還有另外一個好處,就是當你開始使用多個日誌文件時(比如每個線程一個),它會自動正常工作。

0

從下面給出的Logger類中,如果Log類被修改爲使用Lock對象,則調用log(String msg1,String msg2)的線程將使用其新同步策略在線程安全日誌上執行操作。但是調用log(String msg1)方法的線程將始終在Log實例上同步,並且Log類中的所有Lock對象將一次保持不變。在這種情況下,Logger的執行會中斷。這就是爲什麼建議使用私有的最終Lock對象或Lock類而不是客戶端鎖定的原因。

public class Logger { 
    private final Log log; 
    private final Object lock = new Object(); 

    public Logger(Log log) { 
     this.log = log; 
    } 

    public void log(String msg1) {   // log synchronizes on log instance 
     synchronized (log) {   
      log.writeln(msg1);  
     } 
    } 

    public void log(String msg1, String msg2) { // log uses private final lock 
     synchronized (lock) { 
      log.writeln(msg1); 
         log.writeln(msg2); 
     } 
    } 
}