2010-06-22 3 views
1

У меня есть класс, как это:синхронизирующие статические методы в том же классе

public class Utils { 

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

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

Я хочу, чтобы эти два метода должны быть синхронизированы, но не синхронизированы друг с другом т.е. нет двух потоков может обрабатывать метод йоЗотеЬЫпд() в в то же время никакие два потока не могут обрабатывать 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 
    } 
} 

я вижу ответ Скотт Stanchfield использует подобный подход здесь:

How do synchronized static methods work in Java?

, но это лучший способ сделать это? Для меня это кажется неуклюжим, создавая два объекта, только для того, чтобы их можно было использовать для блокировки - есть ли лучший способ сделать это?

ответ

1

Да, это самый простой способ. Хотя объект, который вы блокируете, не должен быть чем-то особенным. Вы могли бы просто сделать их целыми, без заданных значений.

-2

Ваше решение кажется правильным. Обычно я вижу/экземпляры использования объекта в качестве блокировки (вместо строк), как:

public class Utils { 

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

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

Проблемы вы пытаетесь решить связано с ThreadLocal случаев использования класса.

+1

Почему массив ??? –

+1

это на самом деле хуже, чем авторская версия, поскольку никто не знает, какой замок [0] должен защищать - у него нет имени. Единственный полезный момент - использовать новый Object(), а не «STRING» – unbeli

+0

@Tom Hawtin - tackline: что не так с массивом? Мой ответ может быть неправильным, но ваш комментарий ничего не указывает. Дайте вниз, пока не появится лучшее объяснение. – Roman

1

Заблокировать интернированный String s является ошибкой. Если вы запустите FindBugs, я верю, что это укажет на это. Создайте новый экземпляр объекта для блокировки - new Object() или new String("Something informative"). Чтобы увидеть что-то полезное в трассировке стека, когда оно заблокировано, используйте специальный класс для задания.

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

или

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

На самом деле, это, как правило, лучше создать частный внутренний объект (объекты являются действительно мало - сделать математику), чем выставить блокировку через публичный интерфейс.

5

Использование строк - это не очень хорошая идея, потому что одна и та же строка может появиться где-то в другом месте, это будет тот же объект, и вы можете получить зависимости, где вы не то, что они. Просто сделайте

private static final Object DO_SOMETHING_LOCK = new Object(); 

Остальное в порядке.

+0

Вопрос здесь. Значение String связано с именем метода, которое я синхронизирую, поэтому оно не будет отображаться в другом месте, но я беру вашу точку зрения, вместо этого я буду использовать объекты. Я знаю, что мое решение работает, кстати, я не спрашиваю, работает ли оно, но если есть более элегантное решение, которое не связано с созданием объектов исключительно с целью блокировки? – CodeClimber

+0

Создание объектов для блокировки в порядке. В конце концов, это единственное, что вы можете заблокировать на Java, поэтому вы либо создаете его, либо находите подходящий существующий объект. – unbeli

+0

Создание объектов блокировки - очень распространенное решение. –

Смежные вопросы