Home > database >  Java Synchronized account example isn't working as expected
Java Synchronized account example isn't working as expected

Time:11-16

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.....

CodePudding user response:

Your System.out.println is not sync, for example:

  1. At the beginning dollers was 10000 , thread1 and thread2 execute account.deduct2(1); Now dollers is 9998.
  2. thread3 execute account.deduct2(1); Now dollers is 9997.
  3. thread1 and thread2 start printing account#dollars, you will see two 9997.

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....");
            }
        }
  • Related