synchronized初学问题 感兴趣的看下 分不多!!

小小小小小小小白 2014-04-09 05:04:54
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, 大神门指教下这段代码问题在在哪?怎么改进可以实现我想要的结果!
...全文
167 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 10 楼 kevinlifeng 的回复:
其实你这个可以有两种方法解决。第一种就是同步类而不是对象,因为你的new了两个对象,同步了对象而不是类,他们执行自个的,不会相互互斥。如果想让你能得到你要的结果,可以像2楼的那个样,这样是对的。 还有一种方法解决就是,帮你想要互斥的方法放入一个单独的类中,然后这个类的方法用同步,就可以了,这样引用它的对象,方法都是互斥的。
大概懂了点 谢谢了!
kevinlifeng 2014-04-09
  • 打赏
  • 举报
回复
其实你这个可以有两种方法解决。第一种就是同步类而不是对象,因为你的new了两个对象,同步了对象而不是类,他们执行自个的,不会相互互斥。如果想让你能得到你要的结果,可以像2楼的那个样,这样是对的。 还有一种方法解决就是,帮你想要互斥的方法放入一个单独的类中,然后这个类的方法用同步,就可以了,这样引用它的对象,方法都是互斥的。
  • 打赏
  • 举报
回复
引用 7 楼 awajwgluiawa 的回复:
[quote=引用 5 楼 u013266090 的回复:] [quote=引用 3 楼 lixiaohua886 的回复:] 分析你的代码 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值初始化的问题
看了你写的 为什么 只要让p1对线的线程停一秒 就可以了?能不能从内存的角度来解释下?[/quote]因为这里的线程处理速度很快,停一秒后,其实p1的任务已经完成,同时它也不再调用转账方法,所以p1与p2不是共享互斥资源saving[/quote]我又贴了 一种方式 那种方式 不会出现 刚才的问题,为什么 这种方式不会有这样的问题?谢谢了
  • 打赏
  • 举报
回复
为什么 这种写法 不会出现 这样的问题 !!package D2; //通过实现Runable接口 和synchronized 解决线程同步问题 class Account{ private int saving = 0; synchronized public void tansfer(int i){ String name = Thread.currentThread().getName(); int sum = saving; sum+=i; System.out.println(name+"转账"+i+"元,余额共有"+sum+"元"); saving = sum; } } class People implements Runnable{ Account account; int times; //转账次数 public People(Account account,int times){ this.account = account; this.times = times; } @Override public void run() { // TODO Auto-generated method stub for(int i=0;i<times;i++){ account.tansfer(500); } } } public class D2 { public static void main(String[] args) { // TODO Auto-generated method stub Account account = new Account(); People p1 = new People(account, 4); People p2 = new People(account, 3); Thread thread_p1 = new Thread(p1,"小明"); Thread thread_p2 = new Thread(p2, "小红"); thread_p1.start(); thread_p2.start(); } }结果如下 小明转账500元,余额共有500元 小明转账500元,余额共有1000元 小明转账500元,余额共有1500元 小明转账500元,余额共有2000元 小红转账500元,余额共有2500元 小红转账500元,余额共有3000元 小红转账500元,余额共有3500元
Kenzson 2014-04-09
  • 打赏
  • 举报
回复
引用 5 楼 u013266090 的回复:
[quote=引用 3 楼 lixiaohua886 的回复:] 分析你的代码 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值初始化的问题
看了你写的 为什么 只要让p1对线的线程停一秒 就可以了?能不能从内存的角度来解释下?[/quote]因为这里的线程处理速度很快,停一秒后,其实p1的任务已经完成,同时它也不再调用转账方法,所以p1与p2不是共享互斥资源saving
  • 打赏
  • 举报
回复
引用 5 楼 u013266090 的回复:
[quote=引用 3 楼 lixiaohua886 的回复:] 分析你的代码 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值初始化的问题
看了你写的 为什么 只要让p1对线的线程停一秒 就可以了?能不能从内存的角度来解释下?[/quote]好像理解 了 这种处理方式 不就相当于 2个线程不是同步执行了嘛!
  • 打赏
  • 举报
回复
引用 3 楼 lixiaohua886 的回复:
分析你的代码 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值初始化的问题
看了你写的 为什么 只要让p1对线的线程停一秒 就可以了?能不能从内存的角度来解释下?
木鱼121 2014-04-09
  • 打赏
  • 举报
回复
貌似 是我理解错了 2楼是正解
木鱼121 2014-04-09
  • 打赏
  • 举报
回复
分析你的代码 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值初始化的问题
Kenzson 2014-04-09
  • 打赏
  • 举报
回复
上面的方法不是很明智,可以这样来
    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;
        }
    }
Kenzson 2014-04-09
  • 打赏
  • 举报
回复
走的太快,可以这样。
        try {
            Thread.sleep(100);
        } catch (InterruptedException ex) {
            Logger.getLogger(SubClass.class.getName()).log(Level.SEVERE, null, ex);
        }

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧