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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王军行 中级黑马   /  2013-3-8 01:22  /  1619 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 王军行 于 2013-3-8 10:39 编辑

这段代码:
class Bank
{
        private int sum;
        public synchronized void add (int n)
        {               
                        sum = sum +n;
                        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  BankDemo
{
        public static void main(String[] args)
        {
                Cus c = new Cus();
                Thread t1 = new Thread(c);
                Thread t2 = new Thread(c);
                t1.start();
                t2.start();
        }
}
我运行的结果一直是 200 300 400 500 600 600.难道是多核机的问题吗?毕老师视频的银行存钱练习讲解,求解释?

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1 鼓励鼓励

查看全部评分

5 个回复

倒序浏览
本帖最后由 梁耀今 于 2013-3-8 01:53 编辑

这不是多核机的问题,是你编程的思想有点混乱,搞不清楚synchronized的用处,你这里的同步应该是同步数据,你这样用synchronized是达不到你想要的效果,因为你这里是创建的是两个线程,得到两把锁,然后他们是同时修改了共用的数据,所以使,第一次时候得到200,倒数第二次和最后一次同样得到600。正确写法很多,不过正确思路只有一个,就是同步的是数据,而不是线程。
回复 使用道具 举报
你的代码是这样的   try里面应该用 Thread.sleep(10);  你用的wait(10);   用wait(10)怎么就不行呢?
1  用了wait后除非被notify()  notifyAll()  或者中断interrupt()   还有时间到之前  它是不会醒的
2  wait后  会放弃同步  即不再持有锁   

这样就好理解了    假设  t1  加完100 后wait了  t2  进来加100  输出200  然后继续输出300 400 500 600  10毫秒的时间够t2输出完毕了  这时候t1醒了  那就输出呗  600

所以 200 300 400 500 600 600 就是这样来的
回复 使用道具 举报
门文通 发表于 2013-3-8 05:39
你的代码是这样的   try里面应该用 Thread.sleep(10);  你用的wait(10);   用wait(10)怎么就不行呢?
1  ...

谢谢!我只为wait 和sleep都能让线程停下来不知带还有这个区别!
回复 使用道具 举报
王军行 发表于 2013-3-8 10:37
谢谢!我只为wait 和sleep都能让线程停下来不知带还有这个区别!

知道了就行了  互相学习
回复 使用道具 举报
这不是多核的问题,,是多线程问题:

我们先看看sleep():和wait():的区别:

sleep是线程被调用时,占着cpu去睡觉,其他线程不能占用cpu,os认为该线程正在工作,不会让出系统资源,wait是进入等待池等待,让出系统资源,其他线程可以占用cpu,一般wait不会加时间限制,因为如果wait的线程运行资源不够,再出来也没用,要等待其他线程调用notifyall方法唤醒等待池中的所有线程,才会再进入就绪序列等待os分配系统资源,

sleep是静态方法,是谁调用我的那谁就去睡觉,就算是在main线程里调用了线程b的sleep方法,实际上还是main去睡觉,想让线程b去睡觉要在b的代码中掉sleep

sleep(100L)是占用cpu,线程休眠100毫秒,其他进程不能再占用cpu资源,wait(100L)是进入等待池中等待,交出cpu等系统资源供其他进程使用,在这100毫秒中,该线程可以被其他线程notify,但不同的是其他在等待池中的线程不被notify不会出来,但这个线程在等待100毫秒后会自动进入就绪队列等待系统分配资源,换句话说,sleep(100)在100毫秒后肯定会运行,但wait在100毫秒后还有等待os调用分配资源,所以wait100的停止运行时间是不确定的,但至少是100毫秒。

还有些不同点:

1.Thread类的方法:sleep(),yield()等
Object的方法:wait()和notify()等

2.sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。

3.waitl只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用

4.sleep必须捕获异常,而wait不需要捕获异常
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马