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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

package com.heima.duoxiancheng;
/*
* 本文件描述用多线程知识,
* 编写两个储户向银行账户存钱,
* 每次存100,共存6次。
* 说明如何找出线程安全问题的代码
* 和同步函数。
*
*/
public class TongBuHanShu {
public static void main(String[] args) {
  // TODO Auto-generated method stub
  CuHu cu=new CuHu();
  Thread t1=new Thread(cu);
  Thread t2=new Thread(cu);
  t1.start();
  t2.start();
}
}
class Bank{
int sum=0;
  void add(int n){
  Object obj=new Object();
  synchronized (obj) {//发现sum是多线程共享数据,并有多条语句操作它
   //所以用将他们用同步代码块封装起来。又发现这些代码是add(int n)方法的所有代码
   //所以可以用将该方法声明为同步方法,这样就不用用同步代码块将它们封装起来了。
   try {
    sum=sum+n;
    Thread.sleep(10);
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   System.out.println("储户"+Thread.currentThread()+"存入100现在银行账户余额为"+sum);
  }
}
}
class CuHu implements Runnable{
Bank b=new Bank();
@Override
public void run() {
  for(int i=0;i<6;i++){
   b.add(100);
  }
}

}

评分

参与人数 1技术分 +1 收起 理由
李小然 + 1

查看全部评分

3 个回复

倒序浏览
这么晚了还在学习,精神值得嘉奖。
错误在这里,应该把Object对象放到add方法的外面,因为在里面的话是每个线程启动调用这个方法的时候都会创建一个Object对象,这样就导致了有2个Object对象,这样你加的锁就不再是同一个了,我说的能否明白?
  1. void add(int n){
  2.    Object obj=new Object();
复制代码

改成
  1. Object obj = new Object();
  2.         void add(int n) {
  3.                
复制代码

评分

参与人数 1技术分 +1 收起 理由
李小然 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 为了明天 于 2014-5-26 09:17 编辑

void add(int n){
         Object obj=new Object();
         synchronized (obj) {
                   同步代码
          }
}

把Object obj=new Object();定义在add方法内部,每次调用方法都会new一个对象,
synchronized (obj) 判断的标记不是同一个锁,
可以直接用类的字节码文件加锁,
将Object obj=new Object();
         synchronized (obj)

改为
synchronized (TongBuHanShu.class)


评分

参与人数 1技术分 +1 收起 理由
李小然 + 1

查看全部评分

回复 使用道具 举报
谢谢了,基础没学好啊,同步的一大前提,是不是同一个锁
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马