What is a race condition?

后端 未结 18 2504
谎友^
谎友^ 2020-11-21 04:52

When writing multithreaded applications, one of the most common problems experienced is race conditions.

My questions to the community are:

What is the rac

18条回答
  •  [愿得一人]
    2020-11-21 05:07

    Try this basic example for better understanding of race condition:

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

提交回复
热议问题