Issue
I'm using Account example to practice the Java Synchronized.
And here is my code.
Account class
class Account {
public int dollars;
public Account(int d) {
dollars = d;
}
// might fail due to concurrently accessing this method
public synchronized void deduct2(int amount) {
dollars -= amount;
}
@Override
public String toString() {
return "" + dollars;
}
MyThread class
class MyThread extends Thread {
static Account account = new Account(10000);
private int id;
public MyThread(int i) {
id = i;
}
@Override
public void run() {
System.out.println("performing my job ....");
for (int i = 0; i < 100; i++) {
account.deduct2(1);
System.out.println("account " + account + " " + getName() +"performing....");
}
}
ThreadTest class
public class ThreadTest {
public static void main(String args[]) {
new ThreadTest().exec();
System.out.println("main finished");
}
private void exec() {
test1();
}
private void test1() {
Thread thread1 = new MyThread(1);
Thread thread2 = new MyThread(2);
Thread thread3 = new MyThread(3);
thread1.start();
thread2.start();
thread3.start();
}}
Result
main finished
performing my job ....
performing my job ....
performing my job ....
account 9997 Thread-0performing....
account 9997 Thread-2performing....
account 9997 Thread-1performing....
account 9995 Thread-2performing....
account 9996 Thread-0performing....
account 9993 Thread-2performing....
account 9994 Thread-1performing....
account 9991 Thread-2performing....
account 9992 Thread-0performing....
account 9989 Thread-2performing....
account 9990 Thread-1performing....
account 9987 Thread-2performing....
account 9988 Thread-0performing....
account 9985 Thread-2performing....
account 9986 Thread-1performing....
....
account 9713 Thread-1performing....
account 9708 Thread-1performing....
account 9709 Thread-0performing....
account 9706 Thread-0performing....
account 9707 Thread-1performing....
account 9704 Thread-1performing....
account 9705 Thread-0performing....
account 9702 Thread-0performing....
account 9703 Thread-1performing....
account 9701 Thread-0performing....
account 9700 Thread-1performing....
I run three different new Thread, and every new thread deduct 1 for an hundred times. So the result of account dollars is correct(9700).
But I'm confused why the process of account dollars were being deduct is not working as my expected. I assume it would runs like 9999 9998 9997.....
Solution
Your System.out.println
is not sync, for example:
- At the beginning dollers was 10000
,
thread1
andthread2
executeaccount.deduct2(1)
; Now dollers is 9998. thread3
executeaccount.deduct2(1)
; Now dollers is 9997.thread1
andthread2
start printingaccount#dollars
, you will see two9997
.
If you want to print sequentially, put the synchronized
in for loop.(Account#deduct2
does not need to add synchronized
anymore.):
for (int i = 0; i < 100; i++) {
synchronized (account) {
account.deduct2(1);
System.out.println("account " + account + " " + getName() + "performing....");
}
}
Answered By - zysaaa