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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张权 中级黑马   /  2013-3-8 11:42  /  1155 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 张权 于 2013-3-8 14:54 编辑

/*
需求:
银行有一个金库。
有两个储户分别存300员,每次存100,存3次。

*/

/*
//这个代码运行结果正确
class Bank {
        Object obj = new Object();
        private int sum;

        public void add(int n) {
                synchronized (obj) {
                        sum = sum + n;
                        try {
                                wait(10);
                        } catch (Exception e) {
                        }
                        System.out.println("sum = " + sum);
                }
        }
}*/
        class Bank
        {
                private int sum;
                public synchronized void add (int n)
                {               
                                sum = sum +n;
                               //这里的wait改成Thread.sleep(10); 代码运行没问题.问题,为什么用wait时,锁代码块没问题,锁方法就有问题
                                try{wait(10);}catch (Exception e){}
                                System.out.println("sum = "+sum);
                }
        }


class Cus implements Runnable {
        Bank b = new Bank();

        public void run() {

                for (int x = 0; x < 3; x++) {
                        b.add(100);
                }
        }
}

class Demo {
        public static void main(String[] args) {
                Cus c = new Cus();
                Thread t1 = new Thread(c);
                Thread t2 = new Thread(c);
                t1.start();
                t2.start();
        }
}

5 个回复

倒序浏览
sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
回复 使用道具 举报
其实你说的那里,就算换了sleep也是错误的。我说的错误是思想上的错误,当数据小的时候看起来没出错,但大的时候是会出错的,因为同步的时候,wait是释放锁,而sleep是补释放锁的,当你运算次数越多的时候,你就会发现一样是不同步的!
回复 使用道具 举报
梁耀今 发表于 2013-3-8 12:54
其实你说的那里,就算换了sleep也是错误的。我说的错误是思想上的错误,当数据小的时候看起来没出错,但大 ...

哦!!为什么换成sleep也是错的呢?我打印了100个数据没有错误,至于我提的问题我现在终于明白了,以前根本就没有理解,其实调用wait方法的应该是锁的对象.因为我把那个同步函数给改了下,那里的wait改用obj引用调用,就和同步代码块的 效果一样!!!
回复 使用道具 举报
张权 发表于 2013-3-8 14:52
哦!!为什么换成sleep也是错的呢?我打印了100个数据没有错误,至于我提的问题我现在终于明白了,以前根本就 ...

嗯,弄清楚就好了!
回复 使用道具 举报
嗯,要使线层挂起的话,就要用该线程对象调用wait()方法,对于使线程挂起的另一种方式也是得使用线程对象调用wait(),这种方式是wait()和notify()配合使用的,这种方式让wait()方法无限等下去,直到线程接收到notify()或notifyAll()消息为止。
即:thread.wait();  thread.notify();
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马