Programlamada “atomik” ne demektir?


276

Etkili Java kitabında şunları belirtir:

Dil belirtimi, değişkenin türü longveya double[JLS, 17.4.7] olmadığı sürece bir değişkenin okunması veya yazılmasının atomik olduğunu garanti eder .

"Atomik" Java programlama veya genel olarak programlama bağlamında ne anlama gelir?


24
Her seferinde bir işlem.
Subhrajyoti Majumder

1
değişken üzerinde bir seferde yalnızca bir işlem gerçekleştirilebilir.
kaysush


1
felsefe sorularının codereview.stackexchange.com'a
Phlip

Bazı değişkenler varsayılan olarak değil atomik okuma ve yazma var, onları ilan belirten volatile longveya volatile doublemarkaları atom okuma ve atomik yazın.
H2ONaCl

Yanıtlar:


372

İşte bir örnek, çünkü bir örnek genellikle uzun bir açıklamadan daha açıktır. Farz edin ki foobir tür değişkendir long. Aşağıdaki işlem bir atomik işlem değildir:

foo = 65465498L;

Aslında, değişken iki ayrı işlem kullanılarak yazılır: biri ilk 32 biti ve diğeri son 32 biti yazar. Bu, başka bir iş parçacığının değerini okuyabileceği foove ara durumu görebileceği anlamına gelir .

İşlemin atomik hale getirilmesi, işlemin herhangi bir diğer iplikten tek bir atomik (yani parçalara bölünemez) işlem olarak görülmesini sağlamak için senkronizasyon mekanizmalarının kullanılmasından oluşur. Başka bir deyişle, işlem atomik hale getirildikten foosonra, atamadan önce veya atamadan sonra değerini görür . Ama asla ara değer.

Bunu yapmanın basit bir yolu, değişkeni değişken yapmaktır :

private volatile long foo;

Veya değişkene her erişimi senkronize etmek için:

public synchronized void setFoo(long value) {
    this.foo = value;
}

public synchronized long getFoo() {
    return this.foo;
}
// no other use of foo outside of these two methods, unless also synchronized

Veya aşağıdakilerle değiştirmek için AtomicLong:

private AtomicLong foo;

75
Bu 32-bit sistemde çalıştığını varsayar. Ya 64 bit sistem olsaydı? Foo = 65465498L; atomik olmak?
Harke

46
@Harke 64 bit Java çalıştırıyorsanız, evet.
Jeroen

4
Bu C # ve .NET için de geçerli mi? Cevabınız evet ise, bir atom davranışı elde etmek için CLR 64-bit olmalıdır?
Fabiano

5
@Fabiano Uygulanır ve Java'da senkronize edilmiş anahtar kelimeye sahip olmadığımız için bunu .NET'te nasıl başaracağımız aşağıda açıklanmıştır. stackoverflow.com/questions/541194/…
Muffin Man

2
Öyleyse A iş parçacığının uzun bir değer atadığını varsayalım ve B iş parçacığının yarısını okumaya çalışır. A operasyonu atomikse, B ipliği bitene kadar bekleyecek mi? Bu atomik işlemlerin örtülü iplik güvenliği sağlayacağı anlamına mı geliyor?
Teoman shipahi

60

"Atomik işlem", diğer tüm evrelerin bakış açısından anlık görünen bir işlem anlamına gelir. Garanti uygulandığında kısmen tamamlanmış bir işlem hakkında endişelenmenize gerek yoktur.


25

"Sistemin geri kalanına anında gerçekleşiyor gibi görünen" bir şeydir ve bilgi işlem süreçlerinde Doğrusallaştırılabilirlik kategorisine girer . Bağlantılı makaleyi daha fazla alıntılamak için:

Atomisite, eşzamanlı süreçlerden bir izolasyon garantisidir. Ek olarak, atomik işlemler genellikle başarılı veya başarısız tanımına sahiptir - sistemin durumunu başarılı bir şekilde değiştirirler veya belirgin bir etkisi yoktur.

Yani, örneğin, bir veritabanı sistemi bağlamında, 'atomik taahhütler' olabilir, yani ilişkisel bir veritabanında bir güncelleme değişiklik kümesi gönderebilirsiniz ve bu değişikliklerin tümü gönderilecek veya hiçbiri arıza durumunda, bu şekilde veriler bozulmaz ve kilitlerin ve / veya kuyrukların bir sonucu olarak, bir sonraki işlem farklı bir yazma veya okuma olacaktır, ancak ancak bundan sonra . Değişkenler ve iş parçacığı bağlamında bu, belleğe uygulananla aynıdır.

Kişisel alıntı vurgular bu ihtiyacı olduğunu değil tüm durumlarda davranış beklenebilir.


15

Atomik ve Atomik Olmayan Operasyonların bana çok yardımcı olması için bir gönderi buldum .

"Paylaşılan belleğe etki eden bir işlem, diğer iş parçacıklarına göre tek bir adımda tamamlanırsa atomiktir.

Paylaşılan bir bellekte bir atomik depo gerçekleştirildiğinde, başka hiçbir iş parçacığı değişikliği yarı yarıya gözlemleyemez.

Paylaşılan bir değişken üzerinde bir atomik yük gerçekleştirildiğinde, tüm değeri tek bir anda göründüğü haliyle okur. "


14

Aşağıdaki kodda m1 ve m2 yöntemlerini uygulayan birkaç iş parçacığınız varsa:

class SomeClass {
    private int i = 0;

    public void m1() { i = 5; }
    public int m2() { return i; }
}

herhangi bir evre çağrısının m20 veya 5 okuyacağını garanti edersiniz .

Öte yandan, bu kodla (burada iuzun):

class SomeClass {
    private long i = 0;

    public void m1() { i = 1234567890L; }
    public long m2() { return i; }
}

bir iş parçacığı çağrısı m20, 1234567890L veya başka bir rastgele değeri okuyabilir, çünkü ifadenin i = 1234567890La için atomik olması garanti edilmez long(bir JVM iki işlemde ilk 32 biti ve son 32 biti yazabilir ve bir iş parçacığı iarasında gözlemleyebilir ) .


Neden "int" sormazken "uzun" soruna neden oluyor? Lütfen buraya bakın geekswithblogs.net/BlackRabbitCoder/archive/2012/08/09/…
onmyway133

1
@entropy uzun ve çift atamalarının Java'da atomik olduğu garanti edilmez. Böylece, bir ödevin ardından bitlerin yalnızca yarısının güncellendiği uzun bir süre okuyabilirsiniz.
assylias

0

Java'da uzun ve çift dışındaki tüm türlerin okuma ve yazma alanları atomik olarak gerçekleşir ve alan uçucu değiştirici ile bildirilirse, uzun ve çift bile atomik olarak okunur ve yazılır. Yani, ne var ya da orada ne var, ne de% 100 olsun, değişkenlerde herhangi bir ara sonuç olamaz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.