Why the synchronized Synchronize method does not lock member variables

public class Test {
    public static void main(String[] args) {
        Account account=new Account(100);
        Person p1=new Person(account,80);
        Person p2=new Person(account,90);
        p1.start();
        p2.start();
        
    }    
}

class Account{
    int total;    
    public Account(int total) {
        super();
        this.total=total;        
    }    
}

class Person extends Thread{
    private int reduce;
    public Account account;
    public Person(Account account,int reduce) {
    
        this.account=account;
        this.reduce=reduce;
    }
    
    public synchronized void run() {    
        if (account.total-reduce<0) return ;
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        account.total-=reduce;
        System.out.println(Thread.currentThread().getName()+""+reduce);
        System.out.println(Thread.currentThread().getName()+""+account.total);
        
    }
}

Thread-0 take out 80
Thread-0 remaining-70
Thread-1 take out 90
Thread-1 remaining-70

here is a simulated operation of withdrawing money from an account, using the Synchronize method, but the lock failed. I think people say that account is not locked, but
account is also a member of the person object. Doesn"t the Synchronize method lock the person object? why is it not locked here?

Mar.15,2022

p1Magne p2 are two different thread objects. When they enter the Synchronize method run (), they hold the respective locks of p1Mague p2, so they don't have the Synchronize effect at all


.

has been solved. Each object has a monitor to check whether it is locked. There are person objects and account objects. Locking on person objects does not affect the lock of account. This is why account is not locked. After p1 enters the method, p2 reenters the monitor to check account. There is no lock, and it enters successfully. So it's not locked. what is needed here is account's lock.

public void run() {    
        synchronized(account) {
        if (account.total-reduce<0) return ;
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        account.total-=reduce;
        System.out.println(Thread.currentThread().getName()+""+reduce);
        System.out.println(Thread.currentThread().getName()+""+account.total);
        
        }
    }
MySQL Query : SELECT * FROM `codeshelper`.`v9_news` WHERE status=99 AND catid='6' ORDER BY rand() LIMIT 5
MySQL Error : Disk full (/tmp/#sql-temptable-64f5-1b3b9a4-2c2ae.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
MySQL Errno : 1021
Message : Disk full (/tmp/#sql-temptable-64f5-1b3b9a4-2c2ae.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
Need Help?