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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 巩建 于 2013-6-18 19:01 编辑
  1. /*
  2. 卖票的问题。看到毕老师的视频的这部分,突发奇想,于是改了一下程序,想实现修改各个线程名称的功能。
  3. 但本程序没有编译运行错误,为什么运行结果中看不到修改过后的各个线程的名称?
  4. 如果是程序编写有点问题或不合理那该怎么修改才好?
  5. */
  6. class Ticket extends Thread implements Runnable
  7. {
  8.            private static int ticket = 100;
  9.            private String name;
  10.            Ticket(String name)
  11.           {
  12.                    super(name);
  13.           }
  14.           public void run()
  15.          {
  16.                   while(ticket>0)
  17.                  {
  18.                             System.out.println(Thread.currentThread().getName()+"--sale--"+ ticket--);
  19.                  }
  20.          }
  21. }

  22. class ThreadTest1
  23. {
  24.            public static void main(String[] args)
  25.           {
  26.                    Ticket t_1 = new Ticket("one");
  27.                    Ticket t_2 = new Ticket("two");
  28.                    Ticket t_3 = new Ticket("three");
  29.                    Ticket t_4 = new Ticket("four");
  30.                    new Thread(t_1).start();
  31.                    new Thread(t_2).start();
  32.                    new Thread(t_3).start();
  33.                    new Thread(t_4).start();
  34.           }
  35. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
夜默 + 1

查看全部评分

6 个回复

倒序浏览
这个问题论坛里挺多的 多看看视屏
且存在线程不安全。帮你修改了下。
  1. class Ticket extends Thread implements Runnable
  2. {
  3.            private static int ticket = 100;
  4.            private String name;
  5.            Ticket(String name)
  6.           {
  7.              super(name);
  8.           }
  9.           public void run()
  10.          {
  11.               synchronized(this){  //这个地方改加锁的 要不存在线程问题
  12.                                   while(ticket>0)
  13.                                  {  
  14.                                                 //Thread.currentThread().getName() 因为这个地方只是获取线程本身的名字
  15.                                                  // 所以就取不到了
  16.                                       System.out.println(this.getName()+"--sale--"+ ticket--);
  17.                                  }
  18.               }
  19.          }
  20. }

  21. class ThreadTest1
  22. {
  23.            public static void main(String[] args)
  24.           {
  25.                    Ticket t_1 = new Ticket("one");
  26.                    Ticket t_2 = new Ticket("two");
  27.                    Ticket t_3 = new Ticket("three");
  28.                    Ticket t_4 = new Ticket("four");
  29.                    new Thread(t_1).start();
  30.                    new Thread(t_2).start();
  31.                    new Thread(t_3).start();
  32.                    new Thread(t_4).start();
  33.           }
  34. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
夜默 + 1

查看全部评分

回复 使用道具 举报
问题出在这。class Ticket extends Thread implements Runnable
首先这是对线程定义的两种方式,使用一个即可。没必要既继承有实现。
然后问题出在你对构造函数初始化时,因为接口中没有构造函数,所以这个super()语句初始化的是Thread类中的,而你在主函数中定义的线程是使用接口方式执行的,那么创建线程时候传入的参数默认为是Runnable接口的子类,不能有自定义的名字,所以打印的结果还是线程原名。
可将主函数内改写成这样的形式:
  1. Ticket t_1 = new Ticket("one");
  2.                    Ticket t_2 = new Ticket("two");
  3.                    Ticket t_3 = new Ticket("three");
  4.                    Ticket t_4 = new Ticket("four");
  5.                    t_1.start();
  6.                    t_2.start();
  7.                    t_3.start();
  8.                    t_4.start();
复制代码
回复 使用道具 举报
王磊 发表于 2013-6-18 04:00
问题出在这。class Ticket extends Thread implements Runnable
首先这是对线程定义的两种方式,使用一个即 ...

补充:刚刚说的方法是使用Thread方式创建线程
如果用Runnable方式,可修改为
  1. class Ticket extends Thread implements Runnable
  2. {
  3.           private static int ticket = 100;
  4.          
  5.           public void run()
  6.          {
  7.                   while(ticket>0)
  8.                  {
  9.                             System.out.println(Thread.currentThread().getName()+"--sale--"+ ticket--);
  10.                  }
  11.          }
  12. }

  13. class ThreadTest1
  14. {
  15.            public static void main(String[] args)
  16.           {
  17.                    Ticket t_1 = new Ticket();
  18.                    Ticket t_2 = new Ticket();
  19.                    Ticket t_3 = new Ticket();
  20.                    Ticket t_4 = new Ticket();
  21.                    new Thread(t_1,"one").start();
  22.                    new Thread(t_2,"two").start();
  23.                    new Thread(t_3,"three").start();
  24.                    new Thread(t_4,"four").start();
  25.           }
  26. }
复制代码
总之不要两个方法一起用就好。。。对于class Ticket extends Thread implements Runnable位置我没有改,虽然不影响编译,但是最好还是去掉,这样也能明显的看出来用的是Thread方法还是Runnable方法

评分

参与人数 1技术分 +2 收起 理由
夜默 + 2 很给力!

查看全部评分

回复 使用道具 举报
王磊 发表于 2013-6-18 04:06
补充:刚刚说的方法是使用Thread方式创建线程
如果用Runnable方式,可修改为总之不要两个方法一起用就好 ...

其实最初的目的是为了只想通过Runnable接口,在程序中实现对各个线程的名称的更改,发现用currentThread().getName()实现不了,发现currentThread().getName()其实是Thread中的方法,故又继承了它,发现还是实现不了。如果在定义Ticket类的时候,不去继承Thread,只使用Runnable接口,该怎么实现对各个纯种的名称的更改?
回复 使用道具 举报
刘利民 发表于 2013-6-18 07:53
其实最初的目的是为了只想通过Runnable接口,在程序中实现对各个线程的名称的更改,发现用currentThread( ...
  1. class Ticket implements Runnable
  2. {
  3.            private static int ticket = 100;
  4.            private String name;
  5.            Ticket(String name)
  6.           {
  7.             this.name= name;
  8.           }
  9.           public void run()
  10.          {
  11.               
  12.                           while(ticket>0)
  13.                          {  
  14.                                                        
  15.                                   System.out.println(name+"--sale--"+ ticket--);
  16.                          }

  17.          }
  18. }

  19. class ThreadTest1
  20. {
  21.            public static void main(String[] args)
  22.           {
  23.                    Ticket t_1 = new Ticket("one");
  24.                    Ticket t_2 = new Ticket("two");
  25.                    Ticket t_3 = new Ticket("three");
  26.                    Ticket t_4 = new Ticket("four");
  27.                    new Thread(t_1).start();
  28.                    new Thread(t_2).start();
  29.                    new Thread(t_3).start();
  30.                    new Thread(t_4).start();
  31.           }
  32. }
复制代码
你可以这样该下试试,这样就是将Ticket类的对象完全作为创建线程时的参数,并且调用run方法时候,使用的是该参数的名字。
回复 使用道具 举报
夜默 金牌黑马 2013-6-18 19:01:29
7#
问题已解决,有新的问题,继续讨论...
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马