Получение состояния гонки, несмотря на защиту операций записи - Java

Использование библиотеки java.util.concurrent.locks.ReentrantLock следующим образом:

Два потока генерируют случайное число и использовать его для обновления общих переменных account1 и account2, хранящихся в классе Accounts - блокировка используется для защиты записи в общие переменные

package osproj221;
import java.util.concurrent.locks.ReentrantLock;

public class Accounts {
    private int account1,account2;
    private final ReentrantLock mutex;

    public Accounts(){
        account1=account2=0;
        mutex = new ReentrantLock();
    }

    public void updateAccounts(int amt){
        try{
            mutex.lock();
            account1 += amt;
            account2 -= amt;
        }catch(Exception ex){
            System.out.println(ex);
        }finally{mutex.unlock();}
    }

    public int getAccount1(){
        return this.account1;
    }

    public int getAccount2(){
        return this.account2;
    }
}

Мои потоки реализуют интерфейс Runnable следующим образом:

package osproj221;
import java.util.Random;

public class RaceThread implements Runnable {

    private Random myRand = new Random();
    private int counter = 0;
    private Accounts accounts;

    public RaceThread(Accounts accounts){
        this.accounts = accounts;
    }

    public void run(){

        do{
            int r = myRand.nextInt(300);
            r = Math.abs(r);
            accounts.updateAccounts(r);
            counter++;
        }while((accounts.getAccount1() + accounts.getAccount2() == 0));

        System.out.println(counter + " " + accounts.getAccount1() + " " + accounts.getAccount2());
    }

}

и, наконец, мой основной класс

package osproj221;

public class Main {

    public static void main(String[] args) {
        Accounts myAccounts = new Accounts();

        Thread t1 = new Thread(new RaceThread(myAccounts));
        Thread t2 = new Thread(new RaceThread(myAccounts));

        t1.start();
        t2.start();

        try{
            t1.join();
            t2.join();
        }catch(Exception ex){
            System.out.println(ex);
        }

        System.out.println(myAccounts.getAccount1() + " " + myAccounts.getAccount2());

    }

}

это выглядит немного длиннее, чем я думал - извинения. Я ожидал, что ни один из потоков не завершится, потому что account1 + account2 всегда должно быть = 0, поскольку мьютекс обрабатывает защиту обновления account1 и account2. Похоже, что один из потоков завершается, потому что он не выполняет условие account1 + account2 == 0, а другой продолжает работать бесконечно. я запутался!

0
задан Dave Anderson 23 August 2011 в 12:40
поделиться