朋友们,帮我看看这段简单的程序,为什么会出现我说的问题啊?

public class SaveGetMoney implements Runnable{

private static int deposit = 10000;
private byte  flag;
private int dynamicMoney;

public SaveGetMoney(byte flag,int dynamicMoney) {
    super();
    this.flag = flag;
    this.dynamicMoney = dynamicMoney;
}
public void save(int saveCount){
    deposit = deposit + saveCount;
    System.out.println("public void save");
}
public void get(int getCount){
    deposit = deposit - getCount;
    System.out.println("public void get");
}

@Override
public void run() {
    if(flag == 1){
        System.out.println(Thread.currentThread().getName()+" savesavesave: "+deposit);
        save(dynamicMoney);
        System.out.println("当前执行了: "+Thread.currentThread().getName()+"去save了: "+dynamicMoney);
    }
    else if(flag == 0){
        System.out.println(Thread.currentThread().getName()+" getgetget: "+deposit);
        get(dynamicMoney);
        System.out.println("当前执行了: "+Thread.currentThread().getName()+"去get了: "+dynamicMoney);
    }

}

public static void main(String[] args) {
    System.out.println("刚开始的static的deposit: "+deposit);
    new Thread(new SaveGetMoney((byte)1,1000)).start();
    new Thread(new SaveGetMoney((byte)1,500)).start();
    System.out.println("当前执行了: "+Thread.currentThread().getName()+": "+deposit);
}

}
得到的结果为:
刚开始的static的deposit: 10000
Thread-0 savesavesave: 10000
public void save
当前执行了: Thread-0去save了: 1000
当前执行了: main: 10000
Thread-1 savesavesave: 11000
public void save
当前执行了: Thread-1去save了: 500

问题在于:“当前执行了: main: 10000” 这个是为什么啊?我觉得应该是11000啊,不对吗?

那是因为你现在线程数少,线程执行时间短,如果你在第二个线程中加上一段短时间的休眠就会看到你想要的结果。

多线程执行又不是顺序执行的,当第一个线程启动执行时,第二个线程也已启动执行,并且很有可能在你的第一个线程执行存钱操作前就已经开始执行获取金额总数的操作,所以会看到是1000。

看来你没仔细看线程啊。
[code="java"]
1----->new Thread(new SaveGetMoney((byte)1,1000)).start();
2----->new Thread(new SaveGetMoney((byte)1,500)).start();
3----->System.out.println("当前执行了: "+Thread.currentThread().getName()+": "+deposit);
[/code]
这三句,1,2开启线程。3还是主线程。简单地说,1,2,3应该算是同时执行的。但是主线程3的优先级高。所以先运行3了。之后1和2同时执行。至于1,2谁先执行,要看他们的线程优先级了。

这是因为线程的运行并不会像你想的那样啊。
[quote]
public void run() {
if(flag == 1){ ////1
System.out.println(Thread.currentThread().getName()+" savesavesave: "+deposit);
save(dynamicMoney); ////2
System.out.println("当前执行了: "+Thread.currentThread().getName()+"去save了: "+dynamicMoney);
}
else if(flag == 0){ ////3
System.out.println(Thread.currentThread().getName()+" getgetget: "+deposit);
get(dynamicMoney); ////4
System.out.println("当前执行了: "+Thread.currentThread().getName()+"去get了: "+dynamicMoney);
}

}
[/quote]
现在假设有两个线程同时在运行,那么当A 运行至 1 处的时候, 线程 B 可能处于 1 2 3 4 这四处的任何一处。同时,当线程A执行完了 2 处的代码后,线程 B 可能刚执行至 1 处,那么当然就是你看到的那个结果了。
所以,线程的同步是不能靠一个简单和变量来控制的,你需要使用 synchronized 关键字来实现(或者其他同步手段)。

是啊,你的两个线程都执行完毕了。

你可以在 SaveGetMoney 类中声明一个变量
[code="java"]private Object lock = new Object();[/code]
然后,把你的 run() 方法的内容,整个的嵌套在
[code="java"]
synchronized(lock){

}
[/code]
中,再运行看看

你的打印顺序真的是这样的,我运行了多次都不会出现这种情况

刚开始的static的deposit: 10000
Thread-0 savesavesave: 10000
public void save
当前执行了: Thread-0去save了: 1000
当前执行了: main: 11000
Thread-1 savesavesave: 11000
public void save
当前执行了: Thread-1去save了: 500

多线程按理以下两个方法都要用synchronized

[code="java"] public synchronized void save(int saveCount) {
deposit = deposit + saveCount;
System.out.println("public void save");
}

public synchronized void get(int getCount) {
    deposit = deposit - getCount;
    System.out.println("public void get");
}[/code]

它说的主线程是指main这个线程,在这个主线程中启动了你的那两个线程,是你的程序启动的入口。

按你的程序可能我理解错了,主线程的优先级不一定是最高的。优先级高只是先执行的可能性更高而已。你运行看看是不是每次都一样。反正原理就是这样吧。

操作的是同一个数据,只是因为线程的执行时机不同,才会导致你看到上述结果。