Які операції в Java вважаються атомними?


Відповіді:


100
  • усі призначення примітивних типів, за винятком long та double
  • всі завдання посилань
  • усі призначення мінливих змінних
  • усі операції класів java.concurrent.Atomic *

а може і щось більше. Подивіться на jls .

Як зазначалося в коментарях, атомність не означає видимість. Отже, хоча інший потік гарантовано не бачить частково записаного int, він може ніколи не побачити нового значення.

Операції над довгими та подвійними також виконуються на загальноприйнятих 64-бітних процесорах, атомних , хоча гарантій немає. Див. Також цей запит на функцію .


21
Присвоєння довгим та парним розмірамvolatile гарантовано будуть атомними: java.sun.com/docs/books/jls/third_edition/html/memory.html#17.7
Joonas Pulakka

12
Крім того , майте на увазі , що в той час як операції є атомарними, видимість цих операцій може не бути гарантовано в багатопотоковому додатку , якщо спеціальний відхід не береться (подробиці тут спосіб хитромудрих описати в коментарі ..)
NOS

5
64 bit jvm, long and double assignments are also atomic.Ти впевнений? Я б сказав, що вони призначені для скомпільованого коду, а як щодо інтерпретованого коду? Можливо, ти маєш рацію, але чи є якась гарантія?
maaartinus

4
Специфікація все ще не вимагає, щоб 64-розрядні JVM забезпечували атомність довгих і подвійних призначень. java.sun.com/docs/books/jls/third_edition/html/memory.html#17.7 За його відомими словами, "ця поведінка залежить від реалізації". Однак, швидше за все, 64-розрядні віртуальні машини зможуть реалізувати це як атомну операцію.
sjlee

1
ІМХО, звичайні посилальні призначення є атомними, але AtomicReference пропонує більше: compareAndSet та getAndSet, чого не вдалося досягти інакше без синхронізації.
maaartinus

5

На Java читання та запис 32-розрядних чи менших величин гарантовано є атомними.
Під атомними ми маємо на увазі, що кожна дія відбувається в один крок і не може бути перервана. Таким чином, коли ми маємо багатопотокові програми, операції читання та запису безпечні для потоку і не потребують синхронізації.

Наприклад, такий код захищений від потоків:

public class ThreadSafe   
  {  
    private int x;  
    public void setX(int x)  
          {
           this.x = x;
           } 
  }

5
..threadsafe в тому сенсі, що значення завжди буде точно або вихідним, або встановленим значенням. Більшість сучасних значень все ще необов'язково не видно для інших потоків через відсутність "мінливих" або "синхронізованих".
Мікко Вілкман,

1
+1 до того, що каже @MikkoWilkman. Цей фрагмент коду не слід використовувати, оскільки він точно не є безпечним для потоку з точки зору пам'яті.
Knuckles the Echidna

0

Було б здатися , що поступка довгот атомарні, на основі цього методу в AtomicLong.java:

public final void set(long newValue) {
    value = newValue;
}

Зверніть увагу на відсутність будь-якої синхронізації.


3
Подивіться на декларацію value. Це volatile.
maaartinus

2
Те valueє volatileне чинить призначення valueатомних, він просто уникає «публікації» питань.
Lyle Z

7
Це робить і те, і інше, див. JLS, розділ 17.7 : Записи та читання нестабільних довгих та подвійних значень завжди є атомними.
maaartinus

@LyleZ, на мій погляд, найцінніший коментар у цій темі.
stdout
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.