黑马程序员技术交流社区

标题: 线程代码运行时出错!!求解。 [打印本页]

作者: 爪哇攻城狮    时间: 2013-4-11 14:09
标题: 线程代码运行时出错!!求解。
本帖最后由 李松柏 于 2013-4-11 16:35 编辑
  1. class ThreadDemo1
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 TestThread tt = new TestThread();
  6.                 tt.start();
  7.                 tt.start();
  8.                 tt.start();
  9.                 tt.start();
  10.         }
  11. }

  12. class TestThread extends Thread
  13. {
  14.         int tickets = 100;
  15.         public void run()
  16.         {
  17.                 while(true)
  18.                 {
  19.                         if(tickets>0)
  20.                         System.out.println(Thread.currentThread().getName()+" is saling ticket "+tickets--);
  21.                 }
  22.         }
  23. }
复制代码
(代码1)
运行结果:
  1. class ThreadDemo1
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 TestThread tt = new TestThread();
  6.                 new Thread(tt).start();
  7.                 new Thread(tt).start();
  8.                 new Thread(tt).start();
  9.                 new Thread(tt).start();
  10.         }
  11. }

  12. class TestThread implements Runnable
  13. {
  14.         int tickets = 100;
  15.         public void run()
  16.         {
  17.                 while(true)
  18.                 {
  19.                         if(tickets>0)
  20.                         System.out.println(Thread.currentThread().getName()+" is saling ticket "+tickets--);
  21.                 }
  22.         }
  23. }
复制代码
(代码2)

-------------------------------------------------------------
代码1运行出错(如上图)。代码2运行正常!!!
求解??

作者: 王海龙2013    时间: 2013-4-11 14:18
你就这样什么都不做就运行了啊,看完多线程,上了锁就好了
作者: 王海龙2013    时间: 2013-4-11 14:20
  1. /**
  2. 1,定义类实现Runnable接口
  3. 2,覆盖Runnable接口中的run方法(将线程要运行的代码存放在该run方法中)
  4. 3,通过Thread类建立线程对象
  5. 4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数(因为自定义的run方法所属的对象是Runnable接口的子类对象,所以要让线程去指定对象的run方法)
  6. 5,调用Thread类的start方法开启线程并调用Runnable接口子类的run方法

  7. 卖票程序:多个窗口买票
  8. */
  9. class Ticket implements Runnable//实现Runnable接口
  10. {
  11.         private int tick = 10000;
  12.         Object obj = new Object();
  13.         public void run()//将线程要运行的代码存放在该run方法中
  14.         {
  15.                 while(true)
  16.                 {        //多线程执行共享数据的语句

  17.                         synchronized(obj)//同步代码块
  18.                         {
  19.                                 if(tick>0)
  20.                                 {        //由于临时状态,阻塞,多线程可能出现安全隐患

  21.                                         System.out.println(Thread.currentThread().getName()+"..."+ tick--);
  22.                                 }
  23.                         }
  24.                 }
  25.         }
  26. }

  27. class TicketDemo
  28. {
  29.         public static void main(String[] args)
  30.         {
  31.                 Ticket t = new Ticket();//建立Runnable接口的子类对象
  32.                 Thread t1 = new Thread(t);//Thread类建立线程对象,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
  33.                 Thread t2 = new Thread(t);
  34.                 Thread t3 = new Thread(t);       
  35.                 t1.start();//调用Thread类的start方法开启线程并调用Runnable接口子类的run方法
  36.                 t2.start();
  37.                 t3.start();       
  38.         }
  39. }
复制代码

作者: 熊永标    时间: 2013-4-11 14:22
本帖最后由 熊永标 于 2013-4-11 14:24 编辑

继承至thread类所创建的线程不能多次启动,
TestThread tt = new TestThread();

                tt.start();

                tt.start();

                tt.start();

                tt.start();
同是一个线程对象,你启动了四次,当然会报IIIegalThreadStateException异常了,而第二个能正常,是因为每次都会先new一个线程对象出来,然后再启动,每个对象只启动一次,所以运行正常
TestThread tt = new TestThread();

                new Thread(tt).start();

                new Thread(tt).start();

                new Thread(tt).start();

                new Thread(tt).start();
tt实现了Runnable接口,所以把Thread传递到Thread的构造函数,是可以接受的,这样在每次启动线程时,就不会出错了.
作者: 杨冉    时间: 2013-4-11 14:26
你看抛出的异常呀,是一个"IllegalThreadStateException",说明你一个Thread对象重复调用了多次start()方法
你看在这里
  1. class ThreadDemo1

  2. {

  3.         public static void main(String[] args)

  4.         {

  5.                 TestThread tt = new TestThread();  //只实例化了一个对象

  6.                 tt.start();         //下边多次调用start方法,就会抛出IllegalThreadStateException异常

  7.                 tt.start();

  8.                 tt.start();

  9.                 tt.start();

  10.         }

  11. }

复制代码
而下边这段是这样
  1. class ThreadDemo1

  2. {

  3.         public static void main(String[] args)

  4.         {

  5.                 TestThread tt = new TestThread();

  6.                 new Thread(tt).start();         //下面这几个start()方法每一个都是一个新实例化的匿名对象调用的,是不同的对象,自然就不会抛出上述的异常

  7.                 new Thread(tt).start();

  8.                 new Thread(tt).start();

  9.                 new Thread(tt).start();

  10.         }

  11. }

复制代码

作者: Asan    时间: 2013-4-11 14:37
多线程的问题一般都会出现异常,你要cry...catch 捕获  或throw抛出
作者: 打工人    时间: 2013-4-11 14:50
问题解决了就改成已解决




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