Apa itu kondisi balapan?

982

Saat menulis aplikasi multithreaded, salah satu masalah paling umum yang dialami adalah kondisi ras.

Pertanyaan saya kepada komunitas adalah:

Bagaimana kondisi lomba?
Bagaimana Anda mendeteksi mereka?
Bagaimana Anda menanganinya?
Akhirnya, bagaimana Anda mencegahnya terjadi?

bmurphy1976
sumber
3
Ada bab besar dalam Pemrograman Aman untuk Linux HOWTO yang menjelaskan apa itu, dan bagaimana menghindarinya.
Craig H
4
Saya ingin menyebutkan bahwa - tanpa menentukan bahasanya - sebagian besar dari pertanyaan ini tidak dapat dijawab dengan baik, karena dalam bahasa yang berbeda, definisi, konsekuensi dan alat untuk mencegahnya mungkin berbeda.
MikeMB
@MikeMB. Setuju, kecuali ketika menganalisis eksekusi kode byte, seperti itu dilakukan oleh Race Catcher (lihat utas ini stackoverflow.com/a/29361427/1363844 ) kami dapat mengatasi semua sekitar 62 bahasa yang dikompilasi ke kode byte (lihat en.wikipedia.org / wiki / List_of_JVM_languages )
Ben

Jawaban:

1238

Kondisi ras terjadi ketika dua utas atau lebih dapat mengakses data yang dibagikan dan mereka mencoba mengubahnya pada saat yang sama. Karena algoritme penjadwalan utas dapat bertukar antar utas kapan saja, Anda tidak tahu urutan upaya utas untuk mengakses data yang dibagikan. Oleh karena itu, hasil dari perubahan dalam data tergantung pada algoritma penjadwalan thread, yaitu kedua thread "balap" untuk mengakses / mengubah data.

Masalah sering terjadi ketika satu utas melakukan "centang-lalu-bertindak" (mis. "Centang" jika nilainya X, lalu "bertindak" untuk melakukan sesuatu yang bergantung pada nilai menjadi X) dan utas lainnya melakukan sesuatu terhadap nilai di antara tanda "check" dan "act". Misalnya:

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.
}

Intinya, y bisa 10, atau bisa apa saja, tergantung pada apakah utas lain berubah x di antara pemeriksaan dan tindakan. Anda tidak memiliki cara nyata untuk mengetahui.

Untuk mencegah terjadinya kondisi balapan, Anda biasanya akan mengunci di sekitar data yang dibagikan untuk memastikan hanya satu utas yang dapat mengakses data pada suatu waktu. Ini akan berarti sesuatu seperti ini:

// 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
Lehane
sumber
121
Apa yang dilakukan thread lain ketika menemukan kunci? Apakah ini menunggu? Kesalahan?
Brian Ortiz
174
Ya, utas lainnya harus menunggu sampai kunci dilepaskan sebelum dapat melanjutkan. Ini membuatnya sangat penting bahwa kunci dilepaskan oleh utas penahan ketika sudah selesai. Jika tidak pernah melepaskannya, maka utas lainnya akan menunggu tanpa batas.
Lehane
2
@Ian Dalam sistem multithreaded akan selalu ada saat-saat ketika sumber daya perlu dibagikan. Mengatakan bahwa satu pendekatan itu buruk tanpa memberikan alternatif, tidak produktif. Saya selalu mencari cara untuk meningkatkan dan jika ada alternatif saya akan dengan senang hati meneliti dan menimbang pro dan kontra.
Despertar
2
@Despertar ... juga, belum tentu bahwa sumber daya akan selalu perlu dibagi dalam sistem milti-threaded. Misalnya, Anda mungkin memiliki array di mana setiap elemen perlu diproses. Anda mungkin dapat mempartisi array dan memiliki utas untuk setiap partisi dan utas dapat melakukan pekerjaannya secara independen satu sama lain.
Ian Warburton
12
Agar suatu perlombaan terjadi, cukup satu utas mencoba untuk mengubah data yang dibagikan sementara utas lainnya dapat membaca atau mengubahnya.
SomeWittyUsername
213

"Kondisi ras" ada ketika kode multithreaded (atau paralel) yang akan mengakses sumber daya bersama bisa melakukannya sedemikian rupa sehingga menyebabkan hasil yang tidak terduga.

Ambil contoh ini:

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

Jika Anda memiliki 5 utas yang mengeksekusi kode ini sekaligus, nilai x TIDAK AKAN berakhir menjadi 50.000.000. Itu sebenarnya akan bervariasi dengan setiap lari.

Ini karena, agar setiap untaian menambah nilai x, mereka harus melakukan hal berikut: (disederhanakan, jelas)

Ambil nilai x
Tambahkan 1 ke nilai ini
Simpan nilai ini ke x

Setiap utas dapat pada setiap langkah dalam proses ini kapan saja, dan mereka dapat saling menginjak ketika sumber daya bersama dilibatkan. Keadaan x dapat diubah oleh utas lainnya selama waktu antara x sedang dibaca dan ketika itu ditulis kembali.

Katakanlah utas mengambil nilai x, tetapi belum menyimpannya. Thread lain juga dapat mengambil yang sama nilai x (karena tidak ada benang telah berubah itu belum) dan kemudian mereka berdua akan menyimpan sama nilai (x + 1) kembali x!

Contoh:

Thread 1: dibaca x, nilainya 7
Thread 1: tambahkan 1 ke x, nilainya sekarang 8
Thread 2: dibaca x, nilainya 7
Thread 1: menyimpan 8 in x
Thread 2: menambahkan 1 ke x, nilainya sekarang 8
Thread 2: menyimpan 8 in x

Kondisi lomba dapat dihindari dengan menggunakan semacam mekanisme penguncian sebelum kode yang mengakses sumber daya bersama:

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

Di sini, jawabannya muncul 50.000.000 setiap kali.

Untuk lebih lanjut tentang penguncian, cari: mutex, semaphore, bagian kritis, sumber daya bersama.

masalah pribadi
sumber
Lihat jakob.engbloms.se/archives/65 untuk contoh program untuk menguji seberapa cepat hal-hal seperti itu memburuk ... itu benar-benar tergantung pada model memori dari mesin yang Anda jalankan.
jakobengblom2
1
Bagaimana bisa mencapai 50 juta jika harus berhenti di 10 juta?
9
@nocomprende: Dengan 5 utas yang mengeksekusi kode yang sama pada suatu waktu, seperti yang dijelaskan langsung di bawah cuplikan ...
Jon Skeet
4
@ JonSkeet Anda benar, saya bingung dengan i dan x. Terima kasih.
Penguncian cek ganda dalam menerapkan pola Singleton adalah contoh mencegah kondisi balapan.
Bharat Dodeja
150

Apa itu Kondisi Ras?

Anda berencana menonton film pada jam 5 sore. Anda menanyakan tentang ketersediaan tiket pada jam 4 sore. Perwakilan mengatakan bahwa mereka tersedia. Anda bersantai dan mencapai jendela tiket 5 menit sebelum pertunjukan. Saya yakin Anda bisa menebak apa yang terjadi: ini adalah rumah yang penuh. Masalahnya di sini adalah durasi antara cek dan tindakan. Anda bertanya pada 4 dan bertindak pada 5. Sementara itu, orang lain mengambil tiket. Itu adalah kondisi balapan - khususnya skenario "periksa-lalu-bertindak" kondisi lomba.

Bagaimana Anda mendeteksi mereka?

Ulasan kode agama, tes unit multi-utas. Tidak ada jalan pintas. Ada beberapa plugin Eclipse yang muncul pada ini, tetapi belum ada yang stabil.

Bagaimana Anda menangani dan mencegahnya?

Hal terbaik adalah membuat fungsi efek stateless dan bebas efek samping, gunakan immutables sebanyak mungkin. Tetapi itu tidak selalu mungkin. Jadi menggunakan java.util.concurrent.atomic, struktur data bersamaan, sinkronisasi yang tepat, dan concurrency berbasis aktor akan membantu.

Sumber daya terbaik untuk konkurensi adalah JCIP. Anda juga bisa mendapatkan detail lebih lanjut tentang penjelasan di atas di sini .

Vishal Shukla
sumber
Ulasan kode dan tes unit adalah hal sekunder untuk memodelkan aliran di antara telinga Anda, dan membuat penggunaan memori bersama lebih sedikit.
Acumenus
2
Saya menghargai contoh dunia nyata dari kondisi balapan
Tom O.
11
Seperti jawabannya jempol . Solusinya adalah: Anda mengunci tiket antara 4-5 dengan mutex (saling pengecualian, c ++). Di dunia nyata itu disebut reservasi tiket :)
Volt
1
akan menjadi jawaban yang layak jika Anda menjatuhkan bit java-only (pertanyaannya bukan tentang Java, melainkan kondisi ras pada umumnya)
Corey Goldberg
Tidak. Ini bukan kondisi balapan. Dari perspektif "bisnis" Anda hanya menunggu terlalu lama. Tentunya backorder bukanlah solusi. Coba scalper atau beli tiket sebagai asuransi
csherriff
65

Ada perbedaan teknis yang penting antara kondisi balapan dan ras data. Sebagian besar jawaban tampaknya membuat asumsi bahwa istilah-istilah ini setara, tetapi tidak.

Perlombaan data terjadi ketika 2 instruksi mengakses lokasi memori yang sama, setidaknya salah satu dari akses ini adalah tulis dan tidak ada yang terjadi sebelum memesan di antara akses ini. Sekarang apa yang membentuk suatu terjadi sebelum memesan tunduk pada banyak perdebatan, tetapi secara umum pasangan kunci-ulock pada variabel kunci yang sama dan pasangan sinyal-tunggu pada variabel kondisi yang sama menginduksi order terjadi sebelum pesanan.

Kondisi balapan adalah kesalahan semantik. Ini adalah cacat yang terjadi dalam waktu atau urutan peristiwa yang mengarah pada perilaku program yang salah .

Banyak kondisi lomba dapat (dan faktanya) disebabkan oleh perlombaan data, tetapi ini tidak perlu. Sebagai soal fakta, data ras dan kondisi ras tidak diperlukan, atau kondisi yang cukup untuk satu sama lain. Posting blog ini juga menjelaskan perbedaannya dengan sangat baik, dengan contoh transaksi bank sederhana. Berikut adalah contoh sederhana lain yang menjelaskan perbedaannya.

Sekarang setelah kita memahami terminologi, mari kita coba menjawab pertanyaan aslinya.

Mengingat bahwa kondisi ras adalah bug semantik, tidak ada cara umum untuk mendeteksi mereka. Ini karena tidak ada cara untuk memiliki oracle otomatis yang dapat membedakan perilaku program yang benar dan yang salah dalam kasus umum. Deteksi ras merupakan masalah yang tidak dapat dipastikan.

Di sisi lain, ras data memiliki definisi yang tepat yang tidak selalu berhubungan dengan kebenaran, dan karenanya seseorang dapat mendeteksinya. Ada banyak rasa pendeteksi ras data (deteksi ras data statis / dinamis, deteksi ras data berbasis-lockset, yang terjadi sebelum deteksi ras data, deteksi ras data hybrid). Detektor ras data dinamis canggih adalah ThreadSanitizer yang bekerja sangat baik dalam praktiknya.

Menangani perlombaan data secara umum membutuhkan beberapa disiplin pemrograman untuk mendorong terjadi sebelum tepi antara akses ke data bersama (baik selama pengembangan, atau sekali mereka terdeteksi menggunakan alat yang disebutkan di atas). ini dapat dilakukan melalui kunci, variabel kondisi, semaphore, dll. Namun, kita juga dapat menggunakan paradigma pemrograman yang berbeda seperti passing pesan (bukan memori bersama) yang menghindari perlombaan data oleh konstruksi.

Baris Kasikci
sumber
Perbedaannya sangat penting untuk memahami kondisi balapan. Terima kasih!
ProgramCpp
37

Definisi semacam kanonik adalah " ketika dua utas mengakses lokasi yang sama di memori pada saat yang sama, dan setidaknya salah satu akses adalah sebuah tulisan ." Dalam situasi ini, utas "pembaca" mungkin mendapatkan nilai lama atau nilai baru, tergantung pada utas mana yang "memenangkan perlombaan." Ini tidak selalu bug — pada kenyataannya, beberapa algoritma level rendah yang sangat berbulu melakukan ini dengan sengaja — tetapi umumnya harus dihindari. @Steve Gury memberikan contoh yang baik tentang kapan itu mungkin menjadi masalah.

Chris Conway
sumber
3
Bisakah Anda memberi contoh bagaimana kondisi lomba dapat bermanfaat? Googling tidak membantu.
Alex V.
3
@ Alex V. Pada titik ini, saya tidak tahu apa yang saya bicarakan. Saya pikir ini mungkin merupakan referensi untuk pemrograman bebas kunci, tetapi itu tidak benar-benar akurat untuk mengatakan itu tergantung pada kondisi balapan, per se.
Chris Conway
33

Kondisi ras adalah sejenis bug, yang hanya terjadi pada kondisi temporal tertentu.

Contoh: Bayangkan Anda memiliki dua utas, A dan B.

Di Thread A:

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

Di Thread B:

object.a = 0

Jika utas A dipraih sesaat setelah memeriksa objek itu. A bukan nol, B akan melakukannya a = 0, dan ketika utas A akan mendapatkan prosesor, ia akan melakukan "bagi dengan nol".

Bug ini hanya terjadi ketika utas A ditangguhkan tepat setelah pernyataan if, itu sangat jarang, tetapi itu bisa terjadi.

Steve Gury
sumber
21

Kondisi ras tidak hanya terkait dengan perangkat lunak tetapi juga terkait dengan perangkat keras juga. Sebenarnya istilah ini awalnya diciptakan oleh industri perangkat keras.

Menurut wikipedia :

Istilah ini bermula dengan ide dua sinyal saling berpacu untuk mempengaruhi output terlebih dahulu .

Kondisi balapan di sirkuit logika:

masukkan deskripsi gambar di sini

Industri perangkat lunak menggunakan istilah ini tanpa modifikasi, yang membuatnya sedikit sulit untuk dipahami.

Anda perlu melakukan beberapa penggantian untuk memetakannya ke dunia perangkat lunak:

  • "dua sinyal" => "dua utas" / "dua proses"
  • "memengaruhi keluaran" => "memengaruhi beberapa status bersama"

Jadi kondisi balapan dalam industri perangkat lunak berarti "dua utas" / "dua proses" berlomba satu sama lain untuk "mempengaruhi beberapa keadaan bersama", dan hasil akhir dari keadaan bersama akan tergantung pada beberapa perbedaan waktu yang halus, yang dapat disebabkan oleh beberapa spesifik urutan peluncuran thread / proses, penjadwalan thread / proses, dll.

nybon
sumber
20

Kondisi lomba adalah situasi pada pemrograman konkuren di mana dua utas atau proses bersamaan bersaing untuk mendapatkan sumber daya dan kondisi akhir yang dihasilkan tergantung pada siapa yang mendapatkan sumber daya terlebih dahulu.

Jorge Córdoba
sumber
Penjelasan hanya brilian
gokareless
Keadaan akhir apa?
Roman Alexandrovich
1
@RomanAlexandrovich Keadaan akhir dari program ini. Keadaan mengacu pada hal-hal seperti nilai-nilai variabel, dll. Lihat jawaban sempurna Lehane. "Negara" dalam contohnya akan merujuk pada nilai akhir dari 'x' dan 'y'.
AMTerp
19

Kondisi balapan terjadi dalam aplikasi multi-utas atau sistem multi-proses. Suatu kondisi balapan, pada dasarnya, adalah segala sesuatu yang membuat asumsi bahwa dua hal yang tidak berada dalam urutan atau proses yang sama akan terjadi dalam urutan tertentu, tanpa mengambil langkah-langkah untuk memastikannya. Ini terjadi secara umum ketika dua utas menyampaikan pesan dengan mengatur dan memeriksa variabel anggota kelas yang keduanya dapat akses. Hampir selalu ada kondisi lomba ketika satu utas memanggil tidur untuk memberikan utas lain waktu untuk menyelesaikan tugas (kecuali jika tidur itu dalam satu lingkaran, dengan beberapa mekanisme pemeriksaan).

Alat untuk mencegah kondisi balapan tergantung pada bahasa dan OS, tetapi beberapa yang umum adalah mutex, bagian kritis, dan sinyal. Mutex bagus ketika Anda ingin memastikan bahwa hanya Anda yang melakukan sesuatu. Sinyal baik ketika Anda ingin memastikan orang lain selesai melakukan sesuatu. Meminimalkan sumber daya bersama juga dapat membantu mencegah perilaku tak terduga

Mendeteksi kondisi ras bisa sulit, tetapi ada beberapa tanda. Kode yang sangat bergantung pada tidur cenderung pada kondisi balapan, jadi pertama-tama periksa panggilan untuk tidur dalam kode yang terpengaruh. Menambahkan tidur yang sangat panjang juga dapat digunakan untuk debugging untuk mencoba dan memaksakan urutan peristiwa tertentu. Ini dapat berguna untuk mereproduksi perilaku, melihat apakah Anda dapat menghilangkannya dengan mengubah pengaturan waktu, dan untuk menguji solusi. Tidur harus dihapus setelah debugging.

Tanda tangan bahwa seseorang memiliki kondisi balapan, adalah jika ada masalah yang hanya terjadi sebentar-sebentar pada beberapa mesin. Bug yang umum adalah crash dan deadlock. Dengan logging, Anda harus dapat menemukan area yang terkena dampak dan bekerja kembali dari sana.

tsellon
sumber
10

Microsoft sebenarnya telah menerbitkan artikel yang sangat terperinci tentang masalah kondisi dan kebuntuan ini. Abstrak yang paling diringkas darinya adalah paragraf judul:

Kondisi balapan terjadi ketika dua utas mengakses variabel yang dibagi secara bersamaan. Utas pertama membaca variabel, dan utas kedua membaca nilai yang sama dari variabel. Kemudian utas pertama dan utas kedua melakukan operasi mereka pada nilai, dan mereka berlomba untuk melihat utas mana yang dapat menulis nilai terakhir ke variabel bersama. Nilai utas yang menulis nilainya terakhir dipertahankan, karena utas tersebut menulis lebih dari nilai yang ditulis utas sebelumnya.

Konstantin Dinev
sumber
5

Apa itu kondisi balapan?

Situasi ketika proses sangat tergantung pada urutan atau waktu kejadian lainnya.

Sebagai contoh, Prosesor A dan prosesor B keduanya membutuhkan sumber daya yang identik untuk pelaksanaannya.

Bagaimana Anda mendeteksi mereka?

Ada alat untuk mendeteksi kondisi balapan secara otomatis:

Bagaimana Anda menanganinya?

Kondisi ras dapat ditangani oleh Mutex atau Semaphores . Mereka bertindak sebagai kunci memungkinkan suatu proses untuk memperoleh sumber daya berdasarkan persyaratan tertentu untuk mencegah kondisi balapan.

Bagaimana Anda mencegahnya terjadi?

Ada berbagai cara untuk mencegah kondisi balapan, seperti Critical Section Avoidance .

  1. Tidak ada dua proses secara bersamaan di dalam wilayah kritis mereka. ( Pengecualian Saling)
  2. Tidak ada asumsi tentang kecepatan atau jumlah CPU yang dibuat.
  3. Tidak ada proses yang berjalan di luar wilayah kritisnya yang memblokir proses lain.
  4. Tidak ada proses yang harus menunggu selamanya untuk memasuki wilayah kritisnya. (A menunggu sumber daya B, B menunggu sumber daya C, C menunggu sumber daya A)
Adnan Qureshi
sumber
2

Kondisi balapan adalah situasi yang tidak diinginkan yang terjadi ketika perangkat atau sistem mencoba untuk melakukan dua atau lebih operasi pada saat yang sama, tetapi karena sifat perangkat atau sistem, operasi harus dilakukan dalam urutan yang tepat untuk menjadi dilakukan dengan benar.

Dalam memori atau penyimpanan komputer, kondisi balapan dapat terjadi jika perintah untuk membaca dan menulis sejumlah besar data diterima pada saat yang hampir bersamaan, dan mesin berusaha untuk menimpa sebagian atau semua data lama saat data lama masih sedang digunakan. Baca. Hasilnya mungkin satu atau lebih dari yang berikut: komputer crash, "operasi ilegal," pemberitahuan dan penutupan program, kesalahan membaca data lama, atau kesalahan menulis data baru.

dilbag koundal
sumber
2

Berikut adalah contoh Saldo Rekening Bank klasik yang akan membantu pemula memahami Thread di Jawa dengan mudah dalam kondisi balapan:

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));

}
realPK
sumber
1

Anda dapat mencegah kondisi balapan , jika Anda menggunakan kelas "Atom". Alasannya hanyalah utas tidak memisahkan dan mengatur operasi, contohnya di bawah ini:

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

Akibatnya, Anda akan memiliki 7 tautan "ai". Meskipun Anda melakukan dua tindakan, tetapi operasi kedua mengkonfirmasi utas yang sama dan tidak ada utas lain yang akan mengganggu ini, itu berarti tidak ada kondisi balapan!

Aleksei Moshkov
sumber
0

Cobalah contoh dasar ini untuk pemahaman yang lebih baik tentang kondisi balapan:

    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;
        }
    }
}
Morsu
sumber
0

Anda tidak selalu ingin membuang kondisi balapan. Jika Anda memiliki bendera yang dapat dibaca dan ditulis oleh banyak utas, dan bendera ini disetel ke 'selesai' oleh satu utas sehingga utas lainnya berhenti diproses saat bendera ditetapkan ke 'selesai', Anda tidak ingin itu "berlomba kondisi "harus dihilangkan. Bahkan, yang ini bisa disebut sebagai kondisi balapan yang jinak.

Namun, dengan menggunakan alat untuk mendeteksi kondisi balapan, itu akan terlihat sebagai kondisi balapan yang berbahaya.

Lebih detail tentang kondisi balapan di sini, http://msdn.microsoft.com/en-us/magazine/cc546569.aspx .

Kiriloff
sumber
Berdasarkan bahasa apa jawaban Anda?
MikeMB
Terus terang bagi saya bahwa jika Anda memiliki kondisi balapan per se , Anda tidak merancang kode Anda dengan cara yang dikontrol ketat. Yang, meskipun mungkin tidak menjadi masalah dalam kasus teoritis Anda, adalah bukti dari masalah yang lebih besar dengan cara Anda merancang & mengembangkan perangkat lunak. Berharap untuk menghadapi bug kondisi ras yang menyakitkan cepat atau lambat.
Insinyur
0

Pertimbangkan operasi yang harus menampilkan penghitungan segera setelah penghitungan bertambah. mis., segera setelah CounterThread menambah nilai DisplayThread perlu menampilkan nilai yang baru-baru ini diperbarui.

int i = 0;

Keluaran

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

Di sini CounterThread sering mendapatkan kunci dan memperbarui nilai sebelum DisplayThread menampilkannya. Di sini ada kondisi Balapan. Kondisi Balapan dapat diselesaikan dengan menggunakan Sinkronisasi

bharanitharan
sumber
0

Kondisi ras adalah situasi yang tidak diinginkan yang terjadi ketika dua atau lebih proses dapat mengakses dan mengubah data bersama pada saat yang sama. Itu terjadi karena ada akses yang saling bertentangan ke sumber daya. Masalah bagian kritis dapat menyebabkan kondisi balapan. Untuk mengatasi kondisi kritis di antara proses, kami hanya mengambil satu proses pada satu waktu yang menjalankan bagian kritis.

ruam
sumber