Java синхронизировал блок больше чем для 1 объекта?

На каждой платформе я видел, управляющие структуры высокого уровня реализованы как низкий уровень gotos (переходы). Например, виртуальная машина Java имеет код байта Перехода, но ничто, для если, еще, в то время как, поскольку, и т.д.

И некоторые из этих компиляторов создают запутанный код для простого условного блока.

Для ответа на вопрос goto все еще считают вредным люди, которые полагают, что он вреден. Goto облегчает терять преимущества структурного программирования.

В конце, это - Ваша программа; и поэтому Ваше решение. Я предлагаю не использовать goto, пока Вы не в состоянии ответить на свой вопрос сами, но в контексте определенной проблемы.

9
задан Chaitanya 5 December 2009 в 08:11
поделиться

2 ответа

Что бы вы ни делали , не этого делайте:

synchronized (array1) {
  synchronized (array2) {
    // do stuff
  }
}

Это может привести к тупиковой ситуации , если вы не будете очень осторожны. Если вы используете этот подход, вы должны убедиться, что у вас есть неизменный частичный порядок объектов - Google "Dining Philosophers" для обсуждения подводных камней.

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

public static class TwoArrays {
  private int[] array1 = ...
  private int[] array2 = ...
  private final Object LOCK = new Object();

  public void doUpdate() {
    synchronized (LOCK) {
      ...
    }
  }
}

Если вам нужен более детализированный метод, вы хотите использовать параллельные утилиты Java 5+, такие как ReadWriteLock , но это будет более сложным в реализации и подверженным ошибкам.

20
ответ дан 4 December 2019 в 07:14
поделиться

До Java 5 я бы написал примерно следующее:

// pre Java 5 code:
Object lock = new Object();
// ...
synchronized(lock) {
    // do something that requires synchronized access
}

Но начиная с Java 5, я бы использовал классы из java.util.concurrent.locks (лично я не считаю это более сложным или подверженным ошибкам):

// Java 5 Code Using Locks
Lock lock = // ...
lock.lock();
try {
    // do something that requires synchronized access
}
finally {
    lock.unlock();
}

Если вам нужно прочитать - блокировка записи, вот пример, реализованный с использованием блокировок чтения-записи из Java 5:

private ReadWriteLock rwl = new ReentrantReadWriteLock();
private Lock rLock = rwl.readLock();
private Lock wLock = rwl.writeLock();

private List<String> data = new ArrayList<String>();

public String getData(int index) { 
    rLock.lock();
    try {
       return data.get(index);
    } finally {
        rLock.unlock();
    }
}

public void addData(int index, String element) {
    wLock.lock();
    try {
        data.add(index, element);
    } finally {
        wLock.unlock();
    }
}

Конечно, адаптируйте ее под свои нужды.

11
ответ дан 4 December 2019 в 07:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: