黑马程序员技术交流社区

标题: java多线程问题? [打印本页]

作者: 王军行    时间: 2013-3-8 01:22
标题: java多线程问题?
本帖最后由 王军行 于 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.难道是多核机的问题吗?毕老师视频的银行存钱练习讲解,求解释?
作者: 梁耀今    时间: 2013-3-8 01:41
本帖最后由 梁耀今 于 2013-3-8 01:53 编辑

这不是多核机的问题,是你编程的思想有点混乱,搞不清楚synchronized的用处,你这里的同步应该是同步数据,你这样用synchronized是达不到你想要的效果,因为你这里是创建的是两个线程,得到两把锁,然后他们是同时修改了共用的数据,所以使,第一次时候得到200,倒数第二次和最后一次同样得到600。正确写法很多,不过正确思路只有一个,就是同步的是数据,而不是线程。
作者: amen0205    时间: 2013-3-8 05:39
你的代码是这样的   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 10:37
门文通 发表于 2013-3-8 05:39
你的代码是这样的   try里面应该用 Thread.sleep(10);  你用的wait(10);   用wait(10)怎么就不行呢?
1  ...

谢谢!我只为wait 和sleep都能让线程停下来不知带还有这个区别!
作者: amen0205    时间: 2013-3-8 18:41
王军行 发表于 2013-3-8 10:37
谢谢!我只为wait 和sleep都能让线程停下来不知带还有这个区别!

知道了就行了  互相学习
作者: 聂斌    时间: 2013-3-9 13:16
这不是多核的问题,,是多线程问题:

我们先看看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不需要捕获异常




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