黑马程序员技术交流社区

标题: 帮我看下,为什么我的代码没有同步效果 [打印本页]

作者: java木    时间: 2014-5-26 02:25
标题: 帮我看下,为什么我的代码没有同步效果
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);
  }
}

}

作者: 月光海    时间: 2014-5-26 05:57
这么晚了还在学习,精神值得嘉奖。
错误在这里,应该把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.                
复制代码

作者: 为了明天    时间: 2014-5-26 09:15
本帖最后由 为了明天 于 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)



作者: java木    时间: 2014-5-28 04:53
谢谢了,基础没学好啊,同步的一大前提,是不是同一个锁




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2