黑马程序员技术交流社区

标题: 多线程不知道哪里出错了 [打印本页]

作者: madianguo    时间: 2013-3-25 14:51
标题: 多线程不知道哪里出错了
本帖最后由 madianguo 于 2013-3-26 21:01 编辑

  1. public class RunnableDemo {
  2.         public static void main(String[] args) {
  3.                 // TODO Auto-generated method stub
  4.                 Ticket1 t = new Ticket1();
  5.                 Thread t1 = new Thread(t);
  6.                 Thread t2 = new Thread(t);
  7.                 Thread t3 = new Thread(t);

  8.                 t1.start();
  9.                 t2.start();
  10.                 t3.start();               
  11.         }
  12. }

  13. class Ticket1 implements Runnable{
  14.         
  15.         private  int  tick = 1000;
  16.         Object mutex = new Object();
  17.         public void run(){
  18.                 while(true){

  19.                         synchronized (mutex ) {
  20.                                 if (tick > 0)
  21.                                         try {
  22.                                                 Thread.sleep(10);
  23.                                         } catch (InterruptedException e) {
  24.                                         }
  25.                                 System.out.println(Thread.currentThread().getName() + "  "
  26.                                                 + "ticket" + tick--);
  27.                         }
  28.                 }
  29.         }        
  30. }
复制代码
不知道哪里的问题。线程根本没有办法停止。只能强制结束   输出的结果一开始正常,但tick变成负数后,程序还一直运行下去
。。。。。。
Thread-2  ticket-55636Thread-2  ticket-55637
Thread-2  ticket-55638
Thread-2  ticket-55639
Thread-2  ticket-55640
Thread-2  ticket-55641


作者: 谢冬    时间: 2013-3-25 15:13
没有结束循环的语句,while(true)当然不会结束,其实这个代码没有真正的达到共享数据,每new一个线程,就多出1000张票,可以改进:
package com.itheima.tickt;
public class TicktData {
        private int tickt = 1000;
        /*出票方法*/
        public int sail()
        {
                return tickt--;
        }
        /*查票方法*/
        public int cha()
        {
                return tickt;
        }
}
package com.itheima.tickt;

public class TicktWindow extends Thread{
        private TicktData td;
        boolean flag = true;
        public TicktWindow(TicktData td)
        {
                this.td = td;
        }
        public void run()
        {
                        while(true)
                        {
                                synchronized(td){
                                        if(td.cha() < 1)
                                                break;
                                        try {
                                                Thread.sleep(100);
                                        } catch (InterruptedException e) {
                                                e.printStackTrace();
                                        }
                                        System.out.println(Thread.currentThread() + "..." + td.sail());
                                }
                        }
               
        }
       
}
package com.itheima.tickt;

public class TicketDemo {
        public static void main(String[] args) {
                TicktData td = new TicktData();
                new TicktWindow(td).start();
                new TicktWindow(td).start();
                new TicktWindow(td).start();
                new TicktWindow(td).start();
        }
}
作者: 黑马朱超    时间: 2013-3-25 15:17
首先说说程序停不下来的问题:因为你的输出语句被while(true){}包含了,这是个无线循环呀,当时毕老师视频里面停下来是因为他使用CTRll+C 强制退出了的。听视频要留意老师的小动作,他有提示的
再说说你tick变负数后的问题,你if语句的中括号{}呢?你没有中括号的话,那个输出语句一定会执行的撒
作者: HM马明宇    时间: 2013-3-25 15:36

  1. public class RunnableDemo {
  2. public static void main(String[] args) {
  3. // TODO Auto-generated method stub
  4. Ticket1 t = new Ticket1();
  5. Thread t1 = new Thread(t);
  6. Thread t2 = new Thread(t);
  7. Thread t3 = new Thread(t);

  8. t1.start();
  9. t2.start();
  10. t3.start();
  11. }
  12. }

  13. class Ticket1 implements Runnable{

  14. private int tick = 1000;
  15. Object mutex = new Object();
  16. public void run(){
  17. while(true){

  18. synchronized (mutex ) {
  19. if (tick > 0){
  20. try {
  21. Thread.sleep(10);
  22. } catch (InterruptedException e) {
  23. }
  24. System.out.println(Thread.currentThread().getName() + " "
  25. + "ticket" + tick--);
  26. }
  27. }
  28. }
  29. }
  30. }
复制代码
你的其他部分没有错误,但是你的if循环之后没用大括号把循环体包住,相当于判断条件不存在啊,而且你的外层循环是永真死循环,故会一直运行。加上大括号后程序把票卖完后还在运行,不过票数不会变,这时候就要手动停止了。
也可以把if判断语句去掉,直接写在while循环语句中。
希望能帮到你

作者: HM马明宇    时间: 2013-3-25 15:37
光明宇宙 发表于 2013-3-25 15:36
你的其他部分没有错误,但是你的if循环之后没用大括号把循环体包住,相当于判断条件不存在啊,而且你的外层 ...

可能是我更改了代码,没有对齐

  1. public class RunnableDemo {
  2. public static void main(String[] args) {
  3. // TODO Auto-generated method stub
  4. Ticket1 t = new Ticket1();
  5. Thread t1 = new Thread(t);
  6. Thread t2 = new Thread(t);
  7. Thread t3 = new Thread(t);

  8. t1.start();
  9. t2.start();
  10. t3.start();
  11. }
  12. }

  13. class Ticket1 implements Runnable{

  14. private int tick = 1000;
  15. Object mutex = new Object();
  16. public void run(){
  17. while(true){

  18. synchronized (mutex ) {
  19. if (tick > 0){
  20. try {
  21. Thread.sleep(10);
  22. } catch (InterruptedException e) {
  23. }
  24. System.out.println(Thread.currentThread().getName() + " "
  25. + "ticket" + tick--);
  26. }
  27. }
  28. }
  29. }
  30. }
复制代码

作者: 黑马十八期0513    时间: 2013-3-26 16:29
24行,if语句之后需要有大括号,如果没有大括号,默认只控制第一行代码, System.out.println(Thread.currentThread().getName() + "  "  + "ticket" + tick--);这个语句要放在if语句内。
而且,还需要进行一次判定,即if(ticket<0) break
总的来说就是这两个问题, System.out.println(Thread.currentThread().getName() + "  "  + "ticket" + tick--)这个语句根本就不受if(ticket>0)控制,它在wile(true)无限循环体内;另一个就是缺少break,循环结束结束语句。




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