Hi:
I have written the following program to understand synchronization. An instance of class Account has 300$ to begin with. 2
Thread instances of class TransactionThread are trying to access it simultaneously. One thread wants to add 500$ to the balance, the other wants to withdraw 50$ from the Account instance. I have written a simple
JUnit test instead of a simple main class. The problem I have is that the deposit and withdraw are made from the original balance, not the updated balance. that is instead of 300+500-50=750, it does 300+500 and 300-50. I have attached the code snippet. Can anyone point out where I am going wrong. Thanks in advance for the help.
------------Account.java-------------
package threads;
/**
*This class represents an account
*/
public class Account {
private Integer balance=new Integer(300);
synchronized public void deposit(int amount)
{ System.out.println("Deposit: "+ amount);
balance=new Integer((balance.intValue()+amount));
}
synchronized public void withdraw(int amount)
{ System.out.println("Withdraw: "+amount);
balance=new Integer((balance.intValue()-amount));
}
public void printBalance()
{System.out.println("Latest balance is :" + balance);}
}
---------------TransactionThread.java-------------------
package threads;
/**
* This is the thread class. Two instances of this class will try to modify the
* contents of the Account class
*/
public class TransactionThread implements Runnable{
private
String transaction=null;
private int amount=0;
Account myAccount;
public TransactionThread(Account ac,String trans, int amt)
{ myAccount=ac;
transaction=trans;
amount=amt;
}
public void run()
{
if (transaction.equals("deposit"))
{myAccount.deposit(amount);}
else if (transaction.equals("withdraw"))
{myAccount.withdraw(amount);}
myAccount.printBalance();
}
}
--------------------AccountTest.java---------------------
package threads;
import junit.framework.TestCase;
import junit.framework.Test;
import junit.framework.TestSuite;
/** Unit test for the Synchronization example
*/
public class AccountTest extends TestCase{
private TransactionThread tt1,tt2;
private Thread t1,t2;
Account myAccount;
public AccountTest(String name)
{super(name);}
protected void setUp()
{ myAccount=new Account();
tt1=new TransactionThread(myAccount,"deposit",500);
tt2=new TransactionThread(myAccount,"withdraw",50);
t1=new Thread(tt1);
t2=new Thread(tt2);
}
protected void tearDown()
{ myAccount=null;
tt1=null;
tt2=null;
t1=null;
t2=null;
}
public void testDeposit()
{t1.start();}
public void testWithdraw()
{t2.start();}
public static Test suite()
{ TestSuite suite=new TestSuite(AccountTest.class);
return suite;}
public static void main(String args[])
{junit.textui.TestRunner.run(suite());}
}
=============OUTPUT======================
C:\j2sdk1.4.2_02\bin\javaw.exe -classpath C:\IntelliJ-IDEA-3.0.5\lib\junit.jar;C:\j2sdk1.4.2_02\jre\lib\charsets.jar;C:\j2sdk1.4.2_02\jre\lib\jce.jar;C:\j2sdk1.4.2_02\jre\lib\jsse.jar;C:\j2sdk1.4.2_02\jre\lib\plugin.jar;C:\j2sdk1.4.2_02\jre\lib\rt.jar;C:\j2sdk1.4.2_02\jre\lib\sunrsasign.jar;C:\j2sdk1.4.2_02\jre\lib\ext\dnsns.jar;C:\j2sdk1.4.2_02\jre\lib\ext\ldapsec.jar;C:\j2sdk1.4.2_02\jre\lib\ext\localedata.jar;C:\j2sdk1.4.2_02\jre\lib\ext\sunjce_provider.jar;C:\j2sdkee1.2.1\lib\j2ee.jar;C:\j2sdk1.4.2_02\lib\tools.jar;C:\Documents and Settings\Preeti\IdeaProjects\jdbcExp\bin;C:\jars;C:\j2sdk1.4.2_02;C:\j2sdk1.4.2_02\bin;C:\j2sdkee1.2.1\lib\j2ee.jar;C:\j2sdk1.4.2_02\lib\tools.jar;C:\j2sdk1.4.2_02\lib;C:\j2sdkee1.2.1\lib;C:\jars\mysql-connector-java-3.0.10-stable-bin.jar;C:\jars\junit.jar;C:\IntelliJ-IDEA-3.0.5\lib\idea_rt.jar com.intellij.rt.execution.junit.TextTestRunner threads.AccountTest
..
Deposit: 500
Latest balance is :800
Withdraw: 50
Latest balance is :250
Time: 0.125