Какие случаи требуют доступа синхронизированного метода в Java?

with open('file') as f :
    numbers = f.readlines()

last_nums = [ line.split()[-1] for line in numbers ]

line.split() разделит строку на элементы списка, используя пробел в качестве разделителя (если вы не поместите в него аргументы), [-1] получит для вас последний элемент этого списка

19
задан Daniel Spiewak 21 November 2008 в 18:08
поделиться

6 ответов

Это зависит от того, хотите ли Вы, чтобы Ваш класс был ориентирован на многопотоковое исполнение. Большинство классов не должно быть ориентировано на многопотоковое исполнение (для простоты), в этом случае, Вам не нужна синхронизация. При необходимости в нем, чтобы быть ориентированными на многопотоковое исполнение, необходимо синхронизировать доступ , или делают переменную энергозависимой. (Это избегает других потоков, получающих "устаревшие" данные.)

20
ответ дан 30 November 2019 в 02:16
поделиться

synchronized модификатор действительно плох идея и должен избежаться любой ценой. Я думаю, что это похвально, которого Sun пытался сделать блокировку немного легче достигнуть, но synchronized правые дела больше проблемы, чем он стоит.

проблема - то, что synchronized метод является на самом деле просто сахаром синтаксиса для получения блокировки на this и содержание его на время метода. Таким образом, public synchronized void setInstanceVar() было бы эквивалентно чему-то вроде этого:

public void setInstanceVar() {
    synchronized(this) {
        instanceVar++;
    }
}

Это плохо по двум причинам:

  • Весь synchronized методы в том же классе используют ту же самую блокировку, которая уменьшает пропускную способность
  • , Любой может получить доступ к блокировке, включая членов других классов.

нет ничего, чтобы препятствовать тому, чтобы я делал что-то вроде этого в другом классе:

MyClass c = new MyClass();
synchronized(c) {
    ...
}

В том synchronized блок, я держу блокировку, которая требуется всем synchronized методы в [1 111]. Это далее уменьшает пропускную способность и существенно увеличения возможности мертвой блокировки.

А лучший подход должен иметь специализированное lock объект и использовать synchronized(...) блок непосредственно:

public class MyClass {
    private int instanceVar;
    private final Object lock = new Object();     // must be final!

    public void setInstanceVar() {
        synchronized(lock) {
            instanceVar++;
        }
    }
}

, С другой стороны, можно использовать эти java.util.concurrent.Lock интерфейс и java.util.concurrent.locks.ReentrantLock реализация для достижения в основном того же результата (на самом деле, это - то же на Java 6).

37
ответ дан 30 November 2019 в 02:16
поделиться

Если бы Вы хотите сделать этот класс ориентированным на многопотоковое исполнение, я объявил бы instanceVar как volatile удостоверяться, что Вы всегда получаете наиболее обновленное значение из памяти, и также я сделал бы setInstanceVar() synchronized, потому что в JVM инкремент не является атомарной операцией.

private volatile int instanceVar =0;

public synchronized setInstanceVar() { instanceVar++;

}
3
ответ дан 30 November 2019 в 02:16
поделиться

. Примерно, ответ, "он зависит". Синхронизация Вашего метода set и метода считывания здесь только имела бы намеченную цель гарантировать, что несколько потоков не могли считать переменные между каждым, другие увеличивают операции:

 synchronized increment()
 { 
       i++
 }

 synchronized get()
 {
   return i;
  }

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

  synchronized int {
    increment
    return get()
  }

В основном, синхронизация полезна для определения, которое операции, как должны гарантировать, выполнят ориентированный на многопотоковое исполнение (inotherwords, Вы не можете создать ситуацию, где отдельный поток подрывает Вашу операцию и заставляет Ваш класс вести себя нелогично или подрывает то, чем Вы ожидаете, что состояние данных будет). Это - на самом деле большая тема, чем к можно обратиться здесь.

Этот книжный Параллелизм Java на практике превосходен, и конечно намного более надежен, чем я.

1
ответ дан 30 November 2019 в 02:16
поделиться

В Java операции на ints являются атомарными так не, в этом случае Вы не должны синхронизироваться, если все, что Вы делаете, является 1 записью и 1 чтением за один раз.

, Если они были longs или удваиваются, действительно необходимо синхронизироваться, потому что для части длинного/двойного возможно быть обновленным, затем имейте другое чтение потока, затем наконец другая часть обновленного длинного/двойного.

-3
ответ дан 30 November 2019 в 02:16
поделиться

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

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

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

public class MyClass{
    private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    private int myValue = 0;

    public void setValue(){
        rwl.writeLock().lock();
        myValue++;
       rwl.writeLock().unlock();
    }

    public int getValue(){
       rwl.readLock.lock();
       int result = myValue;
       rwl.readLock.unlock();
       return result;
    }
}
1
ответ дан 30 November 2019 в 02:16
поделиться
Другие вопросы по тегам:

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