Ответ 1
Используйте AtomicInteger.
Как мне модифицировать int с помощью атомарного и потокобезопасного использования в Java?
Атомно увеличивать, тестировать и устанавливать, и т.д...?
Используйте AtomicInteger.
Безопасность потоков может быть достигнута с помощью синхронизированных функций. Оберните свой int (или такие данные) в классе, который обеспечивает требуемые функции с помощью синхронизированных методов, например
public class X
{
protected int x;
public synchronized void set( int value )
{
x = value;
}
}
Вы также можете использовать классы из пакета java.util.concurrent.atomic, например. AtomicInteger или AtomicIntegerArray
Я просто хотел точно указать, что не так с этим ответом, в случае, если любые вещи, которые synchronized
могут быть использованы для решения эффектов расы нити
| Thread A | Thread B |
|---------------|------------------|
| read x (x=4) | |
| | read x (x=4) |
| Calculate 4+1 | |
| EAX ← 5 | |
| | Calculate 4+1 |
| | EAX ← 5 |
| Start sync | |
| { | Start sync |
| { x ← 5 | wait |
| { | wait |
| End sync | wait |
| | { |
| | { x ← 5 |
| | { |
| | End sync |
Конечный результат операций:
x = 4;
x += 1;
x += 1;
- это x = 5, а не 6.
Такая же проблема существует с ключевым словом volatile
. Ключевое слово volatile
не избавляет вас от эффектов потоков. Ключевое слово volatile гарантирует, что
Строго говоря, volatile
гарантирует, что операции памяти не переупорядочиваются вокруг изменчивой переменной. Это означает, что вы по-прежнему страдают от:
проблема.
private final static AtomicInteger at = new AtomicInteger();
public void run() {
at.set(7);
int i = at.incrementAndGet();