Yarış koşulu nedir?


982

Çok iş parçacıklı uygulamalar yazarken karşılaşılan en yaygın sorunlardan biri yarış koşullarıdır.

Topluluğa sorularım:

Yarış durumu nedir?
Onları nasıl tespit edersiniz?
Onlarla nasıl başa çıkıyorsunuz?
Son olarak, onların oluşmasını nasıl önlersiniz?


3
Linux NASIL için Güvenli Programlama'da ne olduklarını ve nasıl önleneceklerini anlatan harika bir bölüm var .
Craig H

4
Dili belirtmeksizin, bu sorunun çoğu bölümünün doğru bir şekilde cevaplanamayacağından bahsetmek istiyorum, çünkü farklı dillerde, tanımı, sonuçları ve bunları önleme araçları farklı olabilir.
MikeMB

@MikeMB. Kabul edildi, bayt kodu yürütülmesini analiz ederken, Race Catcher tarafından yapıldığı gibi (bu konuya bakın stackoverflow.com/a/29361427/1363844 ) bayt koduna derlenen yaklaşık 62 dili ele alabiliriz (bkz. En.wikipedia.org / wiki / List_of_JVM_languages )
Ben

Yanıtlar:


1237

İki veya daha fazla iş parçacığı paylaşılan verilere erişebildiğinde ve aynı anda değiştirmeye çalıştıklarında bir yarış durumu oluşur. İş parçacığı zamanlama algoritması her zaman iş parçacıkları arasında geçiş yapabildiği için, iş parçacıklarının paylaşılan verilere erişmeye çalışacağı sırayı bilmiyorsunuz. Bu nedenle, veri değişikliğinin sonucu, iplik programlama algoritmasına bağlıdır, yani her iki iplik de verilere erişmek / verileri değiştirmek için "yarışır".

Bir iş parçacığı "check-then-act" (ör. Değer X ise "check", X değerine bağlı bir şey yapmak için "act") ve başka bir iş parçacığı "kontrol" ve "hareket" arasında. Örneğin:

if (x == 5) // The "Check"
{
   y = x * 2; // The "Act"

   // If another thread changed x in between "if (x == 5)" and "y = x * 2" above,
   // y will not be equal to 10.
}

Nokta, y 10 olabilir veya başka bir iş parçacığının kontrol ve hareket arasında x'i değiştirip değiştirmediğine bağlı olarak herhangi bir şey olabilir. Bilmenin gerçek bir yolu yok.

Yarış koşullarının oluşmasını önlemek için, bir kerede yalnızca bir iş parçacığının verilere erişebilmesini sağlamak için genellikle paylaşılan verilerin etrafına bir kilit koyarsınız. Bu şöyle bir şey anlamına gelir:

// Obtain lock for x
if (x == 5)
{
   y = x * 2; // Now, nothing can change x until the lock is released. 
              // Therefore y = 10
}
// release lock for x

121
Diğer iş parçacığı kilitle karşılaştığında ne yapar? Bekliyor mu? Hata?
Brian Ortiz

173
Evet, diğer iş parçacığının devam edebilmesi için kilidin serbest bırakılmasını beklemesi gerekir. Bu, kilidin, bittiğinde tutma ipliği tarafından serbest bırakılmasını çok önemli hale getirir. Asla serbest bırakmazsa, diğer iplik süresiz olarak bekler.
Lehane

2
@Ian Çok iş parçacıklı bir sistemde her zaman kaynakların paylaşılması gereken zamanlar olacaktır. Alternatiflerden biri olmadan bir yaklaşımın kötü olduğunu söylemek üretken değildir. Ben her zaman geliştirmek için yollar arıyorum ve bir alternatif varsa ben memnuniyetle araştırmak ve profesyonel ve eksilerini tartmak olacaktır.
Despertar

2
@Despertar ... ayrıca, kaynakların her zaman milti iş parçacıklı bir sistemde paylaşılması gerekmeyebilir. Örneğin, her öğenin işlenmesi gereken bir diziniz olabilir. Diziyi bölümlere ayırabilir ve her bölüm için bir iş parçacığına sahip olabilirsiniz ve iş parçacıkları çalışmalarını birbirinden tamamen bağımsız olarak yapabilirler.
Ian Warburton

12
Bir yarışın gerçekleşmesi için, iş parçacıklarının geri kalanı onu okuyabilir veya değiştirebilirken, tek bir iş parçacığının paylaşılan verileri değiştirmeye çalışması yeterlidir.
SomeWittyUsername

213

Paylaşılan bir kaynağa erişecek çok iş parçacıklı (veya başka türlü paralel) bir kod, beklenmedik sonuçlara neden olacak şekilde bunu yapabildiğinde bir "yarış koşulu" vardır.

Bu örneği ele alalım:

for ( int i = 0; i < 10000000; i++ )
{
   x = x + 1; 
}

Bu kodu aynı anda yürüten 5 iş parçacığınız varsa, x değeri 50.000.000 OLMAYACAKTIR. Aslında her çalışma için değişir.

Bunun nedeni, her iş parçacığının x değerini artırması için aşağıdakileri yapmaları gerektiğidir: (basitleştirilmiş, açıkçası)

X değerini al
Bu değere 1 ekle
Bu değeri x olarak sakla

Herhangi bir iş parçacığı bu süreçte herhangi bir zamanda herhangi bir adımda olabilir ve paylaşılan bir kaynak söz konusu olduğunda birbirlerine basabilirler. X'in durumu, x okunuyor ve geri yazılırken başka bir evre tarafından değiştirilebilir.

Bir iş parçacığının x değerini aldığını, ancak henüz kaydetmediğini varsayalım. Başka bir iş parçacığı da aynı x değerini alabilir (çünkü henüz hiçbir iş parçacığı bunu değiştirmedi) ve her ikisi de aynı değeri (x + 1) x cinsinden saklar !

Misal:

Konu 1: x okuyor, değer 7
Konu 1: x'e 1 ekleyin, değer şimdi 8'dir
Konu 2: x okuyor, değer 7
Konu 1: 8'de x depolar
Konu 2: x'e 1 ekler, değer şimdi 8'dir
Konu 2: 8'de x depolar

Paylaşılan kaynağa erişen koddan önce bir tür kilitleme mekanizması kullanılarak yarış koşullarından kaçınılabilir :

for ( int i = 0; i < 10000000; i++ )
{
   //lock x
   x = x + 1; 
   //unlock x
}

Burada cevap her seferinde 50.000.000 olarak çıkıyor.

Kilitleme hakkında daha fazla bilgi için: muteks, semafor, kritik bölüm, paylaşılan kaynak.


Bu tür şeylerin nasıl kötüye gittiğini test etmek için bir program örneği için jakob.engbloms.se/archives/65 adresine bakın ... bu gerçekten üzerinde çalıştığınız makinenin bellek modeline bağlıdır.
jakobengblom2

1
10 milyonda durması gerekiyorsa nasıl 50 milyona ulaşabilir?

9
@nocomprende: Snippet'in hemen altında açıklandığı gibi, aynı kodu aynı anda çalıştıran 5 iş parçacığı tarafından ...
Jon Skeet

4
@JonSkeet Haklısın, i ve x'i karıştırdım. Teşekkür ederim.

Tekton deseninin uygulanmasında çift kontrol kilidi, yarış koşullarının önlenmesine bir örnektir.
Bharat Dodeja

150

Yarış Koşulu nedir?

17: 00'da bir filme gitmeyi planlıyorsunuz. Biletlerin saat 16'da mevcut olup olmadığını soruyorsunuz. Temsilci müsait olduklarını söylüyor. Rahatlayın ve gösteri penceresinden 5 dakika önce bilet penceresine ulaşın. Eminim ne olacağını tahmin edebilirsiniz: tam bir ev. Buradaki sorun, çek ile işlem arasındaki süredir. 4 yaşında sordun ve 5 yaşında davrandın. Bu arada, başka biri biletleri aldı. Bu bir yarış koşulu - özellikle yarış koşullarının "kontrol et-sonra-uygula" senaryosu.

Onları nasıl tespit edersiniz?

Dini kod incelemesi, çok iş parçacıklı birim testleri. Kısayol yok. Bunun üzerinde birkaç Eclipse eklentisi ortaya çıkıyor, ancak henüz kararlı bir şey yok.

Onları nasıl idare edersiniz ve önlersiniz?

En iyi şey, yan etkisiz ve vatansız işlevler oluşturmak, mümkün olduğunca değişmezler kullanmak olacaktır. Ancak bu her zaman mümkün değildir. Yani java.util.concurrent.atomic, eşzamanlı veri yapıları, uygun senkronizasyon ve aktör tabanlı eşzamanlılık yardımcı olacaktır.

Eşzamanlılık için en iyi kaynak JCIP'dir. Yukarıdaki açıklama hakkında daha fazla bilgiyi burada bulabilirsiniz .


Kod incelemeleri ve birim testleri, kulaklarınız arasındaki akışı modellemeye ve paylaşılan hafızayı daha az kullanmaya ikinciltir.
Acumenus

2
Bir yarış koşulunun gerçek dünya örneğini takdir ettim
Tom O.

11
Cevap başparmak gibi . Çözüm: biletleri muteks (karşılıklı istisna, c ++) ile 4-5 arasında kilitliyorsunuz. Gerçek dünyada bilet rezervasyonu denir :)
Volt

1
sadece java bitlerini düşürdüyseniz iyi bir cevap olurdu (soru Java ile ilgili değil, genel olarak yarış koşulları ile ilgilidir)
Corey Goldberg

Hayır. Bu bir yarış koşulu değil. "İş" perspektifinden çok uzun süre beklediniz. Açıkça görülüyor ki, geri sıra bir çözüm değil. Bir soyucu deneyin, aksi takdirde bileti sigorta olarak satın alın
csherriff

65

Yarış koşulları ve veri yarışları arasında önemli bir teknik fark vardır. Çoğu cevap, bu terimlerin eşdeğer olduğu varsayımına sahip gibi görünmektedir, ancak değildir.

Bir veri yarışı, 2 komut aynı bellek konumuna eriştiğinde gerçekleşir, bu erişimlerden en az biri bir yazma işlemidir ve bu erişimler arasında sipariş vermeden önce gerçekleşmez . Şimdi, sipariş vermeden önce bir şey oluşturan şey çok tartışmaya tabidir, ancak genel olarak aynı kilit değişkenindeki ulock-kilit çiftleri ve aynı koşul değişkenindeki bekleme sinyali çiftleri, bir önce-sipariş düzenini başlatır.

Bir yarış koşulu anlamsal bir hatadır. Hatalı program davranışına yol açan olayların zamanlamasında veya sıralamasında ortaya çıkan bir kusurdur .

Birçok yarış koşulu veri yarışlarından kaynaklanabilir (ve aslında buna neden olabilir), ancak bu gerekli değildir. Nitekim, veri yarışları ve ırk koşulları ne gerekli ne de birbiri için yeterli koşul. Bu blog yazısı aynı zamanda basit bir banka işlem örneği ile farkı çok iyi açıklamaktadır. İşte farkı açıklayan başka bir basit örnek .

Şimdi terminolojiyi çivilediğimize göre, orijinal soruyu cevaplamaya çalışalım.

Yarış koşullarının semantik hatalar olduğu göz önüne alındığında, bunları tespit etmenin genel bir yolu yoktur. Bunun nedeni, genel durumda doğru ve yanlış program davranışını ayırt edebilecek otomatik bir kehanete sahip olmanın hiçbir yolu olmamasıdır. Yarış tespiti kararlaştırılamaz bir sorundur.

Öte yandan, veri yarışları, doğrulukla ilgili olması gerekmeyen kesin bir tanıma sahiptir ve bu nedenle bunları algılayabilir. Veri yarışı dedektörlerinin birçok çeşidi vardır (statik / dinamik veri yarışı algılama, lockset tabanlı veri yarışı algılama, önce gerçekleşen veri yarışı algılama, hibrit veri yarışı algılama). Son teknoloji ürünü dinamik veri yarış dedektörü, pratikte çok iyi çalışan ThreadSanitizer'dir .

Genel olarak veri yarışlarını yönetmek, paylaşılan verilere erişim arasında (geliştirme sırasında ya da yukarıda belirtilen araçlar kullanılarak tespit edildikten sonra) kenarlar oluşmadan önce bazı programlama disiplinlerini gerektirir. bu, kilitler, durum değişkenleri, semaforlar, vb. yoluyla yapılabilir. Ancak, inşaat yoluyla veri yarışlarını önleyen mesaj geçirme (paylaşılan bellek yerine) gibi farklı programlama paradigmaları da kullanılabilir.


Fark, yarış koşulunu anlamak için kritik öneme sahiptir. Teşekkürler!
ProgramCpp

37

Bir tür kanonik tanım, " iki iş parçacığı aynı anda bellekte aynı konuma eriştiğinde ve erişimlerden en az biri bir yazma olduğunda ." "Okuyucu" iş parçacığı, hangi iş parçacığının "yarışı kazanacağına" bağlı olarak eski değeri veya yeni değeri alabilir. Bu her zaman bir hata değildir - aslında, bazı gerçekten kıllı düşük seviyeli algoritmalar bunu bilerek yapar - ancak genellikle kaçınılmalıdır. @Steve Gury, ne zaman sorun olabileceğine dair iyi bir örnek veriyor.


3
Yarış koşullarının nasıl faydalı olabileceğine dair bir örnek verebilir misiniz? Google'da yardımcı olmadı.
Alex

3
@Alex V. Bu noktada, neden bahsettiğim hakkında hiçbir fikrim yok. Bunun kilitsiz programlamaya bir referans olabileceğini düşünüyorum, ancak yarış koşullarına bağlı olduğunu söylemek gerçekten doğru değil.
Chris Conway

33

Bir yarış koşulu, sadece belirli zamansal koşullarla gerçekleşen bir tür hatadır.

Örnek: İki iş parçanız olduğunu düşünün, A ve B.

Konu A'da:

if( object.a != 0 )
    object.avg = total / object.a

Konu B'de:

object.a = 0

A nesnesinin o nesneyi kontrol ettikten hemen sonra A işlenirse, B boş olur ve B a = 0iş parçacığı kazanır ve A iş parçacığı işlemciyi kazandığında "sıfıra böl" yapar.

Bu hata yalnızca A iş parçacığının if ifadesinden hemen sonra önlenmesi durumunda oluşur, çok nadirdir, ancak olabilir.


21

Yarış durumu sadece yazılımla ilgili değil, aynı zamanda donanımla da ilgilidir. Aslında bu terim başlangıçta donanım endüstrisi tarafından üretildi.

Wikipedia'ya göre :

Düşüncesiyle vadeli kaynaklanır birbirleriyle yarışırlar iki sinyallere karşı ilk çıkışını etkileyen .

Bir mantık devresinde yarış durumu:

resim açıklamasını buraya girin

Yazılım endüstrisi bu terimi değiştirmeden aldı, bu da anlaşılmasını biraz zorlaştırdı.

Yazılım dünyasına eşlemek için bazı değişiklikler yapmanız gerekir:

  • "iki sinyal" => "iki iş parçacığı" / "iki işlem"
  • "çıktıyı etkiler" => "bazı paylaşılan durumları etkiler"

Dolayısıyla, yazılım endüstrisindeki yarış koşulu, "paylaşılan bir durumu etkilemek" için birbirleriyle yarışan "iki iş parçacığı" / "iki işlem" anlamına gelir ve paylaşılan durumun nihai sonucu, belirli bir özelliğin neden olabileceği bazı ince zamanlama farkına bağlı olacaktır. iş parçacığı / işlem başlatma sırası, iş parçacığı / işlem planlama vb.


20

Yarış koşulu, eşzamanlı programlamada, iki eşzamanlı iş parçacığının veya işlemin bir kaynak için rekabet ettiği ve sonuçta ortaya çıkan son durumun kaynağı ilk kimin aldığına bağlı olduğu bir durumdur.


sadece parlak bir açıklama
gokareless

Neyin son hali?
Roman Alexandrovich

1
@RomanAlexandrovich Programın son hali. Değişkenlerin değerleri gibi şeylere atıfta bulunan devlet vb. Bkz. Lehane'nin mükemmel cevabı. Örneğindeki "durum", "x" ve "y" nin nihai değerlerini ifade eder.
AMTerp

19

Yarış koşulları çok iş parçacıklı uygulamalarda veya çok işlemli sistemlerde ortaya çıkar. Bir yarış koşulu, en temelde, aynı iş parçacığında veya süreçte olmayan iki şeyin, yaptıklarından emin olmak için adımlar atmadan belirli bir sırada olacağı varsayımını yapan her şeydir. Bu, iki iş parçacığı bir sınıfın üye değişkenlerinin her ikisinin de erişebildiğini ayarlayıp denetleyerek iletiler ilettiğinde yaygın olarak gerçekleşir. Bir iş parçacığı bir görevi bitirmek için başka bir iş parçacığı zamanını vermek için uykuyu çağırdığında neredeyse her zaman bir yarış durumu vardır (bu uyku bazı kontrol mekanizmalarıyla döngüde değilse).

Yarış koşullarını önlemeye yönelik araçlar dile ve işletim sistemine bağlıdır, ancak bazı ortak kullanılanlar muteksler, kritik bölümler ve sinyallerdir. Muteksler, bir şey yapan tek kişi olduğunuzdan emin olmak istediğinizde iyidir. Başka birinin bir şey yapmayı bitirdiğinden emin olmak istediğinizde sinyaller iyidir. Paylaşılan kaynakları en aza indirmek beklenmedik davranışları önlemeye de yardımcı olabilir

Yarış koşullarını tespit etmek zor olabilir, ancak birkaç işaret vardır. Büyük ölçüde uyumaya dayanan kod yarış koşullarına yatkındır, bu nedenle önce etkilenen kodda uyku çağrılarını kontrol edin. Özellikle uzun uykular eklemek, belirli bir olay sırasını denemek ve zorlamak için hata ayıklamak için de kullanılabilir. Bu, davranışı yeniden üretmek, şeylerin zamanlamasını değiştirerek yok olup olmayacağını görmek ve uygulamaya konulan çözümleri test etmek için yararlı olabilir. Hata ayıklama işleminden sonra uykular giderilmelidir.

Bununla birlikte, bir yarış koşulunun olduğuna dair imza işareti, sadece bazı makinelerde aralıklı olarak meydana gelen bir sorun varsa. Yaygın hatalar çökme ve kilitlenme olurdu. Günlük kaydıyla, etkilenen bölgeyi bulabilmeniz ve oradan geri çalışabilmeniz gerekir.


10

Microsoft aslında bu yarış koşulları ve çıkmazlarla ilgili gerçekten ayrıntılı bir makale yayınladı . Ondan en özetlenen özet başlık paragrafı olacaktır:

İki iş parçacığı aynı anda paylaşılan bir değişkene eriştiğinde bir yarış durumu oluşur. İlk iş parçacığı değişkeni okur ve ikinci iş parçacığı değişkenden aynı değeri okur. Daha sonra ilk iş parçacığı ve ikinci iş parçacığı işlemlerini değer üzerinde gerçekleştirir ve hangi iş parçacığının paylaşılan değişkene son değeri yazabileceğini görmek için yarışırlar. Bir önceki iş parçacığının yazdığı değerin üzerine iş parçacığı yazdığı için, değerini en son yazan iş parçacığının değeri korunur.


5

Yarış koşulu nedir?

Sürecin kritik olarak diğer olayların sırasına veya zamanlamasına bağlı olduğu durum.

Örneğin, İşlemci A ve işlemci B'nin her ikisi de yürütülmesi için özdeş kaynağa ihtiyaç duyar .

Onları nasıl tespit edersiniz?

Yarış durumunu otomatik olarak tespit etmek için araçlar vardır:

Onlarla nasıl başa çıkıyorsunuz?

Yarış durumu Mutex veya Semaphores tarafından ele alınabilir . Bir kilit görevi görürler, bir sürecin yarış durumunu önlemek için belirli gereksinimlere dayalı bir kaynak elde etmesini sağlar.

Onların oluşmasını nasıl önlersiniz?

Kritik Bölümlerden Kaçınma gibi yarış koşullarını önlemenin çeşitli yolları vardır .

  1. Kritik bölgelerinde aynı anda iki süreç yoktur. ( Karşılıklı Dışlama)
  2. Hızlar veya CPU sayısı hakkında herhangi bir varsayım yapılmamıştır.
  3. Kritik bölgesinin dışında çalışan ve diğer süreçleri engelleyen hiçbir süreç yok.
  4. Hiçbir süreç kritik bölgesine girmek için sonsuza dek beklemek zorunda değildir. (B kaynaklarını bekler, B C kaynaklarını bekler, C A kaynaklarını bekler)

2

Yarış koşulu, bir cihaz veya sistem aynı anda iki veya daha fazla işlem yapmaya çalıştığında ortaya çıkan istenmeyen bir durumdur, ancak cihazın veya sistemin doğası gereği, işlemlerin uygun sırayla yapılması gerekir. doğru yapılır.

Bilgisayar belleğinde veya depolamada, hemen hemen aynı anda büyük miktarda veri okuma ve yazma komutları alınırsa ve bu eski veriler hala devam ederken makine eski verilerin bir kısmının veya tamamının üzerine yazmaya çalışırsa bir yarış durumu oluşabilir. okuyun. Sonuç aşağıdakilerden biri veya daha fazlası olabilir: bilgisayar çökmesi, "geçersiz işlem", programın bildirilmesi ve kapatılması, eski verileri okuma hataları veya yeni verileri yazma hataları.


2

İşte yeni başlayanların Java'daki yarış koşullarını kolayca anlayabilmelerine yardımcı olacak klasik Banka Hesap Bakiyesi örneği:

public class BankAccount {

/**
 * @param args
 */
int accountNumber;
double accountBalance;

public synchronized boolean Deposit(double amount){
    double newAccountBalance=0;
    if(amount<=0){
        return false;
    }
    else {
        newAccountBalance = accountBalance+amount;
        accountBalance=newAccountBalance;
        return true;
    }

}
public synchronized boolean Withdraw(double amount){
    double newAccountBalance=0;
    if(amount>accountBalance){
        return false;
    }
    else{
        newAccountBalance = accountBalance-amount;
        accountBalance=newAccountBalance;
        return true;
    }
}

public static void main(String[] args) {
    // TODO Auto-generated method stub
    BankAccount b = new BankAccount();
    b.accountBalance=2000;
    System.out.println(b.Withdraw(3000));

}

1

Şunları yapabilirsiniz yarış durumu önlemek siz "Atom" sınıflarını kullanırsanız,. Nedeni sadece iş parçacığı işlem almak ve ayarlamak ayrı değil, örnek aşağıdadır:

AtomicInteger ai = new AtomicInteger(2);
ai.getAndAdd(5);

Sonuç olarak, bağlantı "ai" 7 olacak. İki işlem yapmanıza rağmen, her iki işlem de aynı iş parçacığını doğrular ve başka hiçbir iş parçacığı buna müdahale etmez, bu da yarış koşulları olmadığı anlamına gelir!


0

Yarış durumunu daha iyi anlamak için bu temel örneği deneyin:

    public class ThreadRaceCondition {

    /**
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        Account myAccount = new Account(22222222);

        // Expected deposit: 250
        for (int i = 0; i < 50; i++) {
            Transaction t = new Transaction(myAccount,
                    Transaction.TransactionType.DEPOSIT, 5.00);
            t.start();
        }

        // Expected withdrawal: 50
        for (int i = 0; i < 50; i++) {
            Transaction t = new Transaction(myAccount,
                    Transaction.TransactionType.WITHDRAW, 1.00);
            t.start();

        }

        // Temporary sleep to ensure all threads are completed. Don't use in
        // realworld :-)
        Thread.sleep(1000);
        // Expected account balance is 200
        System.out.println("Final Account Balance: "
                + myAccount.getAccountBalance());

    }

}

class Transaction extends Thread {

    public static enum TransactionType {
        DEPOSIT(1), WITHDRAW(2);

        private int value;

        private TransactionType(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }
    };

    private TransactionType transactionType;
    private Account account;
    private double amount;

    /*
     * If transactionType == 1, deposit else if transactionType == 2 withdraw
     */
    public Transaction(Account account, TransactionType transactionType,
            double amount) {
        this.transactionType = transactionType;
        this.account = account;
        this.amount = amount;
    }

    public void run() {
        switch (this.transactionType) {
        case DEPOSIT:
            deposit();
            printBalance();
            break;
        case WITHDRAW:
            withdraw();
            printBalance();
            break;
        default:
            System.out.println("NOT A VALID TRANSACTION");
        }
        ;
    }

    public void deposit() {
        this.account.deposit(this.amount);
    }

    public void withdraw() {
        this.account.withdraw(amount);
    }

    public void printBalance() {
        System.out.println(Thread.currentThread().getName()
                + " : TransactionType: " + this.transactionType + ", Amount: "
                + this.amount);
        System.out.println("Account Balance: "
                + this.account.getAccountBalance());
    }
}

class Account {
    private int accountNumber;
    private double accountBalance;

    public int getAccountNumber() {
        return accountNumber;
    }

    public double getAccountBalance() {
        return accountBalance;
    }

    public Account(int accountNumber) {
        this.accountNumber = accountNumber;
    }

    // If this method is not synchronized, you will see race condition on
    // Remove syncronized keyword to see race condition
    public synchronized boolean deposit(double amount) {
        if (amount < 0) {
            return false;
        } else {
            accountBalance = accountBalance + amount;
            return true;
        }
    }

    // If this method is not synchronized, you will see race condition on
    // Remove syncronized keyword to see race condition
    public synchronized boolean withdraw(double amount) {
        if (amount > accountBalance) {
            return false;
        } else {
            accountBalance = accountBalance - amount;
            return true;
        }
    }
}

0

Her zaman bir yarış koşulunu atmak istemezsiniz. Birden çok iş parçacığı tarafından okunabilen ve yazılabilen bir bayrağınız varsa ve bu işaret bir iş parçacığı tarafından 'tamamlandı' olarak ayarlanmışsa, bayrak 'tamamlandı' olarak ayarlandığında diğer iş parçacığı işlemeyi durdurursa, durum ". Aslında, bu iyi huylu bir yarış durumu olarak adlandırılabilir.

Bununla birlikte, yarış durumunun tespiti için bir araç kullanılarak, zararlı bir yarış koşulu olarak tespit edilecektir.

Yarış durumu hakkında daha fazla ayrıntı için, http://msdn.microsoft.com/en-us/magazine/cc546569.aspx .


Cevabınız hangi dile dayanıyor?
MikeMB

Açıkçası size yarış koşulları varsa geliyor bana se başına , bir sıkı kontrollü bir şekilde kodunuzu mimarisi değildir. Bu, teorik durumunuzda bir sorun olmasa da, yazılımı tasarlama ve geliştirme yönteminizle ilgili daha büyük sorunların kanıtıdır. Er ya da geç ağrılı yarış durumu böcekleri ile karşılaşmayı bekleyin.
Mühendis

0

Sayım arttığında sayımı görüntülemek zorunda olan bir işlemi düşünün. yani., en kısa sürede karşıt- değerini artırır DisplayThread son güncellenen değeri görüntülemek gerekiyor.

int i = 0;

Çıktı

CounterThread -> i = 1  
DisplayThread -> i = 1  
CounterThread -> i = 2  
CounterThread -> i = 3  
CounterThread -> i = 4  
DisplayThread -> i = 4

İşte karşıt- sıkça kilidi alır ve daha önce değeri günceller DisplayThread görüntüler o. İşte bir Yarış koşulu var. Yarış Durumu Senkronizasyon kullanılarak çözülebilir


0

Bir yarış koşulu, iki veya daha fazla işlemin paylaşılan verilere aynı anda erişebilmesi ve değiştirebilmesi durumunda ortaya çıkan istenmeyen bir durumdur. Kritik bölüm problemi yarış durumuna neden olabilir. Süreç arasındaki kritik durumu çözmek için, kritik bölümü yürüten bir seferde sadece bir süreç gerçekleştirdik.

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.