如何在JAVA中重现竞争条件?

时间:2015-01-12 00:56:08

标签: java multithreading

我正在学习java多线程并尝试在JAVA中创建竞争条件。这是我的代码。

package com.company;

public class Account  {
    private double balance = 100;

    public  double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }
    public   boolean withdraw(double amount,String name){

        if(this.getBalance()>amount){
            this.setBalance(this.getBalance() - amount);
            System.out.println(Thread.currentThread().getName() + " withdraw " + amount);
            System.out.println("Hello,  " + Thread.currentThread().getName() + " You current balance is " + this.getBalance());

            return true;
        }
        else{
            System.out.println("Sorry, " + Thread.currentThread().getName() + ". Your current balance is " + this.getBalance() + " and you  cannot withdraw " + amount);
            //System.out.println("Welcome,  " + Thread.currentThread().getName() + " You current balance is " + this.getBalance());

            return false;
        }
    }
}

和主要课程

package com.company;
public class Main implements Runnable {
    Account account = new Account();
    public static void main(String[] args){
            Main main = new Main();
            for(int i= 0; i< 2; i++) {
                Thread c1 = new Thread(main, "customer" + i);
                c1.start();
            }
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "'s balance is " + account.getBalance());
        account.withdraw(60, Thread.currentThread().getName());
        //
    }
}

假设这应该产生竞争条件,两个客户同时提取60美元,而getBalance()应该告诉我每个定制CAN提取60美元,每个客户的余额为40美元。但我永远不能重现这一点。我做错了什么?

1 个答案:

答案 0 :(得分:1)

重现竞争条件并不一定容易。它通常取决于线程调度程序的时间。

你可以通过让你的一个线程睡眠来影响它

if (this.getBalance() > amount) {
    if (Thread.currentThread().getName().equals("customer0"))
        try {
            Thread.sleep(1); // simulates a quicker thread context switch
        } catch (InterruptedException e) {}
    this.setBalance(this.getBalance() - amount);
    System.out.println(Thread.currentThread().getName() + " withdraw " + amount);
    System.out.println("Hello,  " + Thread.currentThread().getName() + " You current balance is " + this.getBalance());

    return true;
}

请注意,即使这不是保证。它适用于我的系统,它可能不适合你的系统。这就是为什么竞争条件很烦人的原因。它们很难一致地复制。