package com.test;public class ThreadTest{
public static void main(String[] args) {
Bank bank = new Bank();
Thread th1 = new MyThread(bank);
Thread th2 = new MyThread(bank);

th1.start();
th2.start();
}
}class Bank{
private int money = 1000;
public Object getMoney (int getMoney){
synchronized (this){
while(getMoney < 0 || getMoney > money){
return "ERROR!";
}
money -= getMoney;
return getMoney;
}
}
}class MyThread extends Thread{
Bank bank;
MyThread(Bank bank){
this.bank = bank;
}
@Override
public void run() {
System.out.println(bank.getMoney(800));
}
}这是代码 建立两个线程,调用synchronized方法,却是并发 结果输出ERROR! 800 顺序不定,求问这是为何?

解决方案 »

  1.   

    因为你的两个
    th1.start();
    th2.start();
    是启动了两个线程,运行了2个run,两个run同时调用System.out.println(bank.getMoney(800))你只能保证同步块中肯定是getMoney先为800,然后返回了800,此时已经出了同步块,有可能还没轮到System.out.println(bank.getMoney(800))执行,而轮到另一个bank.getMoney(800)执行,此时会返回error,由于两次的System.out.println(bank.getMoney(800))跟锁没有关系,所以不能保证这两个语句谁先执行,所以不能确定先打印哪个。
    如果你在
    synchronized (this){
    while(getMoney < 0 || getMoney > money){
    return "ERROR!";
    }
    System.out.println("[" + getMoney + "]");
    money -= getMoney;
    return getMoney;
    }插入一个输出,那么肯定是先输出800。这个问题的原因其实就是同步块控制的范围小了,超出同步块的范围就控制不了顺序了。
      

  2.   

    你的线程对象传的是同一个bank:Bank bank = new Bank();
    当你th1.start()后
    money -= getMoney;
    money变成 1000-800 =200了
    因为下面代码
    synchronized (this){
    while(getMoney < 0 || getMoney > money){
    return "ERROR!";
    }
    是线程安全的,所以当下一个线程执行这段代码的时候,money==200 getMoney > money 是true
    进入while循环,返回"ERROR!" 至于800是前面一个线程返回的
    为什么顺序不定,这个就要看调度了
      

  3.   

    楼主笨笨,你这样肯定不行,要不你起个千把个start,或者这样也可以
    synchronized (this){
    Thread.sleep(1000);
    while(getMoney < 0 || getMoney > money){
    return "ERROR!";
    }休眠一下,然后你再看看效果吧。