日期:2014-05-20  浏览次数:20727 次

synchronized初学问题 感兴趣的看下 分不多!!
package D2;
class People2 extends Thread{
int times;//转账次数
private static int saving = 0;//余额
public People2(String name,int times){
super(name);
this.times = times;
}
public void tansfer(int i){
String name = Thread.currentThread().getName();
synchronized(this){
int sum = saving;
sum+=i;
System.out.println(name+"转账"+i+"元,余额共有"+sum+"元");
saving = sum;
}
}
 public void run(){
for(int i=0;i<times;i++){
tansfer(400);
//System.out.println(name);
}
System.out.println(saving);
}
}
public class D3 {

/**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
People2 p1 = new People2("小明",3);
People2 p2 = new People2("小白",4);
p1.setPriority(Thread.MAX_PRIORITY);
p1.start();
p2.start();
}

}
结果如下:
小明转账400元,余额共有400元
小白转账400元,余额共有400元
小明转账400元,余额共有800元
小白转账400元,余额共有800元
小明转账400元,余额共有1200元
1200
小白转账400元,余额共有1200元
小白转账400元,余额共有1600元
1600

这个结果不是我想的答案  我想的答案是想得到 总数的 也就是说  7次转账的总额 2800,  大神门指教下这段代码问题在在哪?怎么改进可以实现我想要的结果!
------解决方案--------------------
上面的方法不是很明智,可以这样来
    public void tansfer(int i) {
        String name = Thread.currentThread().getName();
        synchronized (People2.class) {
            int sum = saving;
            sum += i;
            System.out.println(name + "转账" + i + "元,余额共有" + sum + "元");
            saving = sum;
        }
    }

------解决方案--------------------
 分析你的代码  private static int saving = 0;//余额   
这块代码你初始化的时候,saving都是0;
People2 p1 = new People2("小明",3);
People2 p2 = new People2("小白",4);

所以,p1.start();  p2.start();这两个线程开始时候都是从 0开始相加;   故:你的出来的值  都是各自单独相加所得

不信 你用这段代码测试下,
public static void main(String[] args) throws InterruptedException {
People2 p1 = new People2("小明", 3);
p1.setPriority(Thread.MAX_PRIORITY);
p1.start();
Thread.currentThread().sleep(1000);
People2 p2 = new People2("小白", 4);//这样初始化的时候就不是从0开始了  
p2.start();
}

运行结果:
小明转账400元,余额共有400元
小明转账400元,余额共有800元
小明转账400元,余额共有1200元
1200
小白转账400元,余额共有1600元
小白转账400元,余额共有2000元
小白转账400元,余额共有2400元
小白转账400元,余额共有2800元
2800

所以你代码问题处在  saving值初始化的问题
------解决方案--------------------
其实你这个可以有两种方法解决。第一种就是同步类而不是对象,因为你的new了两个对象,同步了对象而不是类,他们执行自个的,不会相互互斥。如果想让你能得到你要的结果,可以像2楼的那个样,这样是对的。
还有一种方法解决就是,帮你想要互斥的方法放入一个单独的类中,然后这个类的方法用同步,就可以了,这样引用它的对象,方法都是互斥的。