Using the java.util.concurrent.locks.ReentrantLock library as follows:
Two threads generate a random number and use it to update the shared variables account1 and account2 stored in class Accounts – a lock is used to protect the writing to the shared vars
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;
}
}
My threads implement the Runnable interface as follows:
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());
}
}
and finally my Main class
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());
}
}
that looks a little longer than i thought it would – apologies. I would expect that neither of the threads would terminate, because account1+account2 should always = 0 as the mutex handles protecting the updating of account1 and account2. What seems to happen is that one of the threads exits because it fails the account1+account2==0 condition, and the other one continues indefinitely. im confused!
It’s because you’re not locking the reads on your getters. This means thread 2 can read the data in an inconsistent state, while thread 1 is updating the data (between += and -=).
The problem can happen as follows:
Thread 1:
Thread 2:
Thread 1:
The solution:
Unfortunately you can’t simply synchonize your getters individually I would instead recommend a new get method:
and in
RaceThread.run()change the while condition to: