黑马程序员技术交流社区

标题: 關於多線程的問題 [打印本页]

作者: 林铁柱    时间: 2011-12-21 08:40
标题: 關於多線程的問題
本帖最后由 林铁柱 于 2011-12-21 10:13 编辑

    昨天晚上看畢老師的視頻=====黑马程序员_毕向东_Java基础视频教程第11天-08-多线程(创建线程-实现Runnable接口)=====在這節課里,我按照老師講的做了筆記,同樣是運行代碼我的怎麼就出了問題?
   一下是代碼部份:
class  Ticket implements Runnable//extends Thread
{
        private int tick = 100;
        Object obj = new Object();
        public void run()
        {
                while(true)
                {
                        synchronized(obj)
                        {
                                if(tick>0)
                                {
                                        try
                                        {
                                                Thread.sleep(10);
                                        }
                                        catch (Exception e){}
                                        System.out.println(Thread.currentThread().getName()+"....sale : "+tick--);
                                }
                        }
                }
        }
}
       
class TicketDemo2
{
        public static void main(String[] args)
        {
               
                Ticket t = new Ticket();
               
                Thread t1 = new Thread(t);
                Thread t2 = new Thread(t);
                Thread t3 = new Thread(t);
                Thread t4 = new Thread(t);

                t1.start();
                t2.start();
                t3.start();
                t4.start();
               
                /*
                Ticket t1 = new Ticket();
                Ticket t2 = new Ticket();
                Ticket t3 = new Ticket();
                Ticket t4 = new Ticket();
               
                t1.start();
                t2.start();
                t3.start();
                t4.start();
                */
        }
}
      程序運行出現兩個錯誤:
    1、只出現Thread-0,其他線程貌似為啟動
      2、程序運行到最后,不退出java VM,也不繼續運行



    在下實在想不出癥結之所在,特在此求助,希望有大神級的人才幫我解決這個問題。



    還有,大家說我們在用暴風看電影時候,突然點一下“暫停”,是不是調用了類似于Thread.wait()這樣的方法呢??
作者: 海中的游弋草    时间: 2011-12-21 09:11
这样你可以把程序代码中的 private int tick = 100  这个值设置的大点 为10000,你再运行程序看一下运行结果,就可以很清楚的看到线程一二三四都能够交互运行。关于终止的线程,我这样给你解释说,当你调用一个线程的interrupt方法会把线程的状态改为中断态,但是interrupt方法只作用于那些因为执行了sleep、wait、join方法而休眠的线程,使他们不再休眠,同时会抛出 InterruptedException异常。比如一个线程A正在sleep中,这时候另外一个程序里去调用A的interrupt方法,这时就会迫使 A停止休眠而抛出InterruptedException异常;而如果线程A没有处于上面提到的三种休眠状态时被interrupt,这样就只是把线程 A的状态改为interruptted,但是不会影响线程A的继续执行。
如何停止一个线程呢?用stop方法吗?肯定不行,这个方法由于不安全已经过时,不推荐使用,下面的例子提供了一个常用的停止线程的方法,例子中在线程中引入一个属性来控制,当需要停止线程时,只需要调用shutDownThread()方法即可,因为在线程的run()方法中会循环检测这个属性的值,为true正常运行,为false时不会进入循环,线程就可以结束.
作者: 林铁柱    时间: 2011-12-21 09:21
海中的游弋草 发表于 2011-12-21 09:11
这样你可以把程序代码中的 private int tick = 100  这个值设置的大点 为10000,你再运行程序看一下运行结 ...

爲什麽我的電腦要把tick設置的那麼大才有效果呢??我開的程序也不多啊
作者: songxingchao    时间: 2011-12-21 09:25
本帖最后由 songxingchao 于 2011-12-21 09:26 编辑

Thread.sleep(10);  睡眠时间太短,可能效果不明显。 改成1000会好很多。
while(true)  还有你的子线程里是死循环,没有退出机制, 改成while(tick>0) 试试 ,   后面的if(tick>0) 可以不用了。
只是没有 synchronized  tick变量, 会出现负数。
Thread-3....sale : 1
Thread-2....sale : 0
Thread-1....sale : -1
Thread-0....sale : -2

作者: 刘基军    时间: 2011-12-21 09:32
1、只出現Thread-0,其他線程貌似為啟動
---这并不是出错了,只是说明cpu的执行权都是被线程Thread-0抢到了,如1楼所说,将tick值增大就可以看到明显的现象。
2、程序運行到最后,不退出java VM,也不繼續運行
---这是因为while(true)循环中,虽然tick卖完了,但是没有退出循环的结束条件,

while(true)
                {
                        synchronized(obj)
                        {
                                if(tick>0)
                                {
                                        try
                                        {
                                                Thread.sleep(10);
                                        }
                                        catch (Exception e){}
                                        System.out.println(Thread.currentThread().getName()+"....sale : "+tick--);
                                }
                        }
                }

作者: 林铁柱    时间: 2011-12-21 09:40
monghuan 发表于 2011-12-21 09:32
1、只出現Thread-0,其他線程貌似為啟動
---这并不是出错了,只是说明cpu的执行权都是被线程Thread-0抢到了 ...

明白了。。3Q
作者: 海中的游弋草    时间: 2011-12-21 09:43
这样你可以设置线程的优先级。代码如下 你看以看一下
*/
        public static void main(String[] args) {
                Ticket t = new Ticket();
        
        Thread t1 = new Thread(t);
        //t1.setPriority(Thread.NORM_PRIORITY-3);
        Thread t2 = new Thread(t);
        t2.setPriority(Thread.NORM_PRIORITY+3);//设置优先级为8
        Thread t3 = new Thread(t);
        Thread t4 = new Thread(t);
        t4.setPriority(Thread.NORM_PRIORITY-3);//设置优先级2
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        
        try {
                        Thread.sleep(1000);
                } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
        
      
        }
作者: 胡家福    时间: 2011-12-21 10:03
楼上正解,我把你的程序运行了一遍,情况跟你一样,tick = 100时,也只能看到一个线程,但只要设定tick = 1000,就可以看到其他线程了
线程都是随机抢执行权,谁抢到谁运行,只要循环次数够多,就一定能看到

至于循环不终止,是因为while(true)里面的条件恒为真,所以循环一直在运行,没有输出是因为if(tick>0)里面的tick大于0的条件已经不满足,所以不执行打印输出
这就出现了一直在循环,但又没有输出的情况。




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