2012-10-15 27 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); 
     } 
    } 
}