黑马程序员技术交流社区

标题: 多线程创建的3个问题,截图真长 [打印本页]

作者: 黑马朱超    时间: 2013-3-18 00:04
标题: 多线程创建的3个问题,截图真长
本帖最后由 黑马朱超 于 2013-3-18 15:30 编辑

今天看到了多线程的内容,选择Thread方法创建线程,在run语句中依次执行两次打印语句。
下面代码我写的是卖火车票的栗子,创建2个进程去分别卖100张票。
  1. //两个窗口分别卖100张车票
  2.     class Ticket extends Thread
  3. {
  4.     //    private String name;//(1)
  5.     private  int tick =100;//如果不加static的话,那么默认情况下,是每个进程都执行可以买100张票,而不是几个进程一起买100张票
  6.     private int remain;
  7.      Ticket(String name)
  8.     {
  9.         super(name);//把对象的实参作为线程的名称,如果不用这个的话,默认的线程名称形式为Thread-*
  10.         //this.renmin =name;//(2)  通过(1)(2)把对象的实参作为对象的name一个属性
  11.     }
  12.     public void run()
  13.     {
  14.         
  15.         while(true)
  16.         {
  17.             if(tick>0)
  18.             {
  19.             System.out.println(currentThread().getName()+"sale"+tick--);
  20.             System.out.println("----------------"+this.getName()+" 余票"+tick);
  21.              }

  22.             
  23.         }

  24.     }      

  25. }
  26. class TicketDemo
  27. {
  28.     public static void main(String[] args)
  29.     {
  30.         Ticket t1 =new Ticket("第1窗口");
  31.         Ticket t2 = new Ticket("第2窗口");
  32.             t1.start();
  33.             t2.start();
  34.         }
  35.     }
  36.             
  37.                      
复制代码

问题有3个,都在运行结果中红色框出来了
1:为毛我要卖100张票,但是它们却只内部保留了?难道也和铁道部一样么?当我把tick设置为30的时候,是OK的。汗!
2:我的run函数中有2个打印语句,可能执行了第一个打印语句就进程就被阻塞了?如果是这样,有没有办法能让两个语句捆绑执行,就是说我运行一个run,把里面的语句都执行完了再切换(别告诉我说写到一个语句里面哈)
3:我这个票都卖完了,但是我的程序没有结束。while(true)继续循环中,一下就把我电脑CPU满了。如果我在if(tick>0){}
语句后写if(tick==0){return;}程序会正常。但是毕老师的视频里面没有写这个语句照样可以正常结束。很纳闷。





作者: 李尧    时间: 2013-3-18 01:05
1.这个我真没看出来问题在哪...
2.这是因为多线程的情况下一个线程还没执行完 cpu切换出去执行另一个线程了,后面的视频老毕就会说到同步代码块来解决这个问题了.而且我看你的代码 ticket不是共享数据,如果是的话,结果还可能会出现卖了-1,-2张票,这就是没同步的结果.
3.while(true)的内部没加限制条件的话就是无限循环,需要ctrl+c来强制结束.可能你看的老毕视频跟我的不一样吧...
作者: 黑马朱超    时间: 2013-3-18 01:23
李尧 发表于 2013-3-18 01:05
1.这个我真没看出来问题在哪...
2.这是因为多线程的情况下一个线程还没执行完 cpu切换出去执行另一个线程了 ...

对于问题2,当时我还没有看到后面的安全性的内容,呵呵。早知道就一起看了就没有这么多问题了,呵呵
对于问题3,的确是我看漏了,老毕用了ctrl+c 取消运行的。
作者: 谢冬    时间: 2013-3-18 01:25
你这个代码有点问题,每一个线程开启就是100张票,没有真正意义上的达到共享数据,
当tickt>0的时候,tickt--,当然会出现0号票,可以对这个代码进行改进,如果你不想把票数写死,可以再初始化的时候指定,
package com.itheima.tickt;
public class TicktData {
        private int tickt = 100;
        /*出票方法*/
        public int sail()
        {
                return tickt--;
        }
        /*查票方法*/
        public int cha()
        {
                return 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());
                                }
                        }
        }
       
}
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-18 01:30
黑马朱超 发表于 2013-3-18 01:23
对于问题2,当时我还没有看到后面的安全性的内容,呵呵。早知道就一起看了就没有这么多问题了,呵呵
对于 ...

兄弟,你的问题1搞清楚了么,我还是没搞清楚.....求解吖...
作者: 冯超    时间: 2013-3-18 09:28
zi 小,本来就近视
作者: 李晓峰    时间: 2013-3-18 09:53
路过。。
作者: 黑马朱超    时间: 2013-3-18 13:21
李尧 发表于 2013-3-18 01:30
兄弟,你的问题1搞清楚了么,我还是没搞清楚.....求解吖...

没有啊,要不你把这代码复制到你电脑编译试试,看会不会是我电脑的问题?
作者: 黑马朱超    时间: 2013-3-18 13:21
李尧 发表于 2013-3-18 01:30
兄弟,你的问题1搞清楚了么,我还是没搞清楚.....求解吖...

没有啊,要不你把这代码复制到你电脑编译试试,看会不会是我电脑的问题?
作者: 李尧    时间: 2013-3-18 14:52
黑马朱超 发表于 2013-3-18 13:21
没有啊,要不你把这代码复制到你电脑编译试试,看会不会是我电脑的问题? ...

我测试下,没有你说的问题哎,都能卖完.....
作者: 黑马朱超    时间: 2013-3-18 15:27
李尧 发表于 2013-3-18 14:52
我测试下,没有你说的问题哎,都能卖完.....

恩,看来是我昨天rp不行,呵呵

作者: 黑马朱超    时间: 2013-3-18 15:30
谢冬 发表于 2013-3-18 01:25
你这个代码有点问题,每一个线程开启就是100张票,没有真正意义上的达到共享数据,
当tickt>0的时候,tickt ...

恩,谢谢。你的代码写的很好,也很规范...




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