Java 在重载方法上使用同步

Java 在重载方法上使用同步,java,multithreading,Java,Multithreading,因此,我正在编写一个方法,它接受一组参数并将它们写入日志文件。但是,传递给该方法的参数的类型和数量并不总是相同的,这使得我实现了该方法的重载版本。此外,此方法可由并行运行的多个线程访问。我的问题是,在每个重载方法之前使用synchronized,是控制对整个方法的访问,还是只控制对方法的每个重载版本的访问?如果是后者,是否有其他方法控制对日志文件的访问?如果所有方法都是同步的(并且您使用相同的实例调用它们),则每个方法之间都会出现互斥。(前提是您的方法不是静态的。如果您的方法都是静态的,同样适用

因此,我正在编写一个方法,它接受一组参数并将它们写入日志文件。但是,传递给该方法的参数的类型和数量并不总是相同的,这使得我实现了该方法的重载版本。此外,此方法可由并行运行的多个线程访问。我的问题是,在每个重载方法之前使用
synchronized
,是控制对整个方法的访问,还是只控制对方法的每个重载版本的访问?如果是后者,是否有其他方法控制对日志文件的访问?

如果所有方法都是同步的(并且您使用相同的实例调用它们),则每个方法之间都会出现互斥。(前提是您的方法不是静态的。如果您的方法都是静态的,同样适用,但您正在类本身上同步。如果您混合使用静态和非静态方法,那么……不要这样做。)

但是在公共可访问对象(您的日志对象必须是)上进行同步并不是一个特别好的主意。你最好这样做:

public class Logger {
    private final Object LOCK = new Object();

    public void log(String s) {
        synchronized (LOCK) {
           //write to log
        }
    }

    public void log(int i) {
        synchronized (LOCK) {
           //write to log
        }
    }
 }

这样,如果外部有人选择在您的
记录器
实例上同步,则不会干扰类的内部行为。

您尝试过吗?我还建议阅读(以及下面关于内在锁的章节),这只是重载方法。将
synchronized
添加到实例方法相当于将整个方法体包装在
synchronized(this){…}
中。您锁定的是对象而不是方法。
在可公开访问的对象(您的日志记录对象必须是)上同步这不是一个特别好的主意
为什么不呢?@Cratylus解释在最后一段。基本上,如果有人拥有你的对象的实例,他们可以在上面进行同步。如果对象本身依赖于相同的同步来实现正确的功能,那么您可以通过这种方式从外部“中断”它。假设有一个线程与记录器对象同步一个不相关的操作,该操作需要2分钟。这意味着每一个试图写入日志消息的线程都会被阻塞2分钟。那么,我是否只需要同步线程用来调用日志方法的对象?根据我的想象,我在包含线程的类中创建并初始化一个对象,并在每个线程中执行类似于
synchronize(object)
的操作。这样行吗?这也引出了当对象不可用时会发生什么的问题。由于日志需要包含特定操作发生的确切时间,如果对象不可用,是否需要保存包含操作时间的消息(例如缓冲区)?