在同一个类中同步静态方法

时间:2010-06-22 13:47:00

标签: java synchronization

我有一个这样的课程:

public class Utils {

    public static void doSomething() {
        // doSomething code
    }

    public static void doSomethingElse() {
        // doSomethingElse code
    }
}

我希望这两个方法同步但不能彼此同步,即没有两个线程可以同时处理doSomething()方法,没有两个线程可以同时处理doSomethingElse()但是它可以一个处理doSomething()方法的线程,另一个处理doSomethingElse()方法。

我已经实现了这样的事情:

public class Utils {

    private static final String DO_SOMETHING_LOCK = "DO_SOMETHING_LOCK";
    private static final String DO_SOMETHING_ELSE_LOCK = "DO_SOMETHING_ELSE_LOCK";

    public static void doSomething() {
        synchronized(DO_SOMETHING_LOCK) {
            // doSomething code
        }
    }

    public static void doSomethingElse() {
        synchronized(DO_SOMETHING_ELSE_LOCK) {
        // doSomethingElse code
    }
}

我看到Scott Stanchfield的回应采用了类似的方法:

How do synchronized static methods work in Java?

但这是最好的方法吗?对我来说似乎有点笨拙,创造了两个对象,只是用于锁定 - 有更好的方法吗?

4 个答案:

答案 0 :(得分:5)

使用字符串不是一个好主意,因为相同的字符串可能出现在其他地方,它将是同一个对象,您可以获得依赖项,而不是它们。只是做

private static final Object DO_SOMETHING_LOCK = new Object();

其余的都没问题。

答案 1 :(得分:1)

是的,这是最简单的方法。虽然,你锁定的对象不一定是特别的。你可以让它们成为没有设置值的整数。

答案 2 :(得分:1)

锁定实习String是一个错误。如果您运行FindBugs,我相信它会为您指出这一点。为锁定创建对象的新实例 - new Object()new String("Something informative")。要在堆栈跟踪锁定时查看有用的内容,请使用该作业的自定义类。

private final Object lock = new Object() { };

private static final class MyLock { }
private final Object lock = new MyLock();

事实上,创建私有内部对象(对象非常小 - 做数学)通常比通过公共接口公开锁更好。

答案 3 :(得分:-2)

您的解决方案似乎是正确的。我经常看到/使用Object的实例作为锁(而不是字符串),如:

public class Utils {

    private static final Object[] lock = new Object[] { new Object(), new Object() };

    public static void doSomething() {
        synchronized(lock[0]) {
            // doSomething code
        }
    }
    ...
}

您尝试解决的问题与ThreadLocal类用例有关。