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取出80
Thread-1取出90
Thread-0剩余-70
Thread-1剩余-70模仿的账户取钱操作,好像是因为同步锁没锁住account,但是synchronized不是把person对象上锁了吗,
account也是person对象成员啊为什么没锁住?
到底怎么去判断要对哪个对象上锁,怎么判断上锁成功没呢?

解决方案 »

  1.   

    从你描述的需求来看,你的代码里需要加锁的是account对象,而不是person对象。修改下(未调试),供参考:
    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{
        // Abel: 加一个类锁。这种方法很低效,应该把锁加到账户上。这里只是为了指出代码问题。
        private static Object lock = new Object();    private int reduce;
        public Account account;
        public Person(Account account,int reduce) {
         
            this.account=account;
            this.reduce=reduce;
        }    // Abel: 改为使用类静态对象lock加锁     
        public void run() {   
          synchronized(lock) {
            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);
          }
        }
    }
      

  2.   

    synchronized只锁定对象,每个对象只有一个锁(lock)与之相关联public synchronized void run() {...}
    等价于public void run( 
    synchronized (this){...}
    ) P1和P2的this不是同一个