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楼的那个样,这样是对的。
还有一种方法解决就是,帮你想要互斥的方法放入一个单独的类中,然后这个类的方法用同步,就可以了,这样引用它的对象,方法都是互斥的。