A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

李云锋

中级黑马

  • 黑马币:40

  • 帖子:98

  • 精华:0

© 李云锋 中级黑马   /  2014-4-10 11:15  /  999 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

class ThreadDemo4
{
        public static void main(String[] args)
        {
                Consumer c=new Consumer();
                Thread t1=new Thread(c);
                Thread t2=new Thread(c);
                t1.start();
                t2.start();
        }
}
//定义一个银行类
class Bank
{
        private int sum;
        Object obj=new Object();
        public void add(int num){
        sum+=num;
        System.out.println("sum="+num+"..."+Thread.currentThread().getName());
        }
}
//定义一个客户类
class Consumer        implements Runnable
{
        private Bank bank=new Bank();
        public void run(){
        for(int i=0;i<3;i++){
        bank.add(100);    //一次存100,循环3次
        }
        }

}
这个是毕老师讲课的一个小程序:2个人去银行存钱,总共存3次一次存一百,然后打印出银行的总金额
这个程序不安全性的问题是add方法内,如果先执行sum+=num这句话,然后被别的线程抢去执行,就会发生错误(有时候同时输出两个200,但为什么不同时输出两个300或者其他呢),我现在把add内方法改写成System.out.println("sum="+(sum+=num)+"..."+Thread.currentThread().getName());,去掉上面这句,为什么还会出现这种问题?

评分

参与人数 1技术分 +1 收起 理由
zzkang0206 + 1

查看全部评分

4 个回复

倒序浏览
也是可能出现300或者是其他的的,因为cpu在执行的时候是不停的在进程中进行切换的,比如当
  1. sum+=num;
  2. //线程1第二次执行到这里,此时线程2第一次/执行到这里,则num的值就变为了300,然后线程1和线程2执行打印语句就会出现两个300了。当然这具有一定的随机性,因为线程1和线程2获得cpu的执行权是不确定的    System.out.println("sum="+num+"..."+Thread.currentThread().getName());
复制代码

其实你将+=num写在里面和写在外面其实没什么大的区别,
因为sum是共享数据,所以要使用同步代码块
  1. synchronized(Bank.class)
  2. {
  3.       sum+=num;
  4.       System.out.println("sum="+num+"..."+Thread.currentThread().getName());
  5. }
复制代码

让执行该代码时,只能有一个进程执行,执行完了才让其他进程来执行

评分

参与人数 1技术分 +1 收起 理由
zzkang0206 + 1

查看全部评分

回复 使用道具 举报
fufeng 发表于 2014-4-10 21:29
也是可能出现300或者是其他的的,因为cpu在执行的时候是不停的在进程中进行切换的,比如当

其实你将+=num ...

谢谢您的见解
回复 使用道具 举报
理论上时可以出现的,400,,500都可能
回复 使用道具 举报
可能出现两个300
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马