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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 醉演星松 中级黑马   /  2015-7-22 23:58  /  591 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

如何停止线程?
        过去用stop不过现在已经过时

我们知道。开启多线程运行,运行代码通常是循环结构
所以只要控停止循环,就可以让run方法结束,也就是线程结束

特殊情况是:
当线程处于了冻结状态,
线程由于处于冻结状态,并读不到标记,那么线程就不会结束

当没有指定的方式让冻结的线程恢复到运行状态中来的时候,就需要对冻结进行解除!
解决是:
        Thread类提供了该方法   interrupt();
        该方法可以解除wait(),sleep();join()

  1. class Test implements Runnable
  2. {
  3.         private boolean flag = true;
  4.         //public void run()不加同步,没有changeFlag()方法,就只有线程0和线程1在交替执行,死循环,,,没有到main线程
  5.         //public void run()不加同步,有changeFlag()方法,线程0和线程1,mian线程交替执行。正常结束
  6.         public synchronized void run()//加上同步,其实只有一个线程在运行run()里面的内容,threa0和main线程交替,正常结束
  7.                                                                         //因为线程同步。里面又是条件总是满足的循环(直到changeFlag()执行)
  8.         {
  9.                 while(flag)
  10.                 {               
  11.                         try       
  12.                         {
  13.                                 wait();//看下面的分析
  14.                         }

  15.                         catch (InterruptedException e)
  16.                         {
  17.                                 System.out.println(Thread.currentThread().getName()+"**exception");
  18.                                 flag = false;
  19.                         }
  20.                         System.out.println(Thread.currentThread().getName()+"...run");
  21.                 }
  22.         }
  23.         public void changeFlag()
  24.         {
  25.                 flag = false;
  26.         }
  27. }
  28. class InterruptThread
  29. {
  30.         public static void main(String[] args)
  31.         {
  32.                 Test t = new Test();
  33.                 Thread t1 = new Thread(t);
  34.                 Thread t2 = new Thread(t);
  35.                 t1.start();
  36.                 t2.start();

  37.                 int num =0;
  38.                 while(true)
  39.                 {
  40.                         if(num++ == 6000)
  41.                         {
  42.                                 t1.interrupt();
  43.                                 t2.interrupt();
  44.                                 //t.changeFlag();
  45.                                 break;
  46.                         }
  47.                         System.out.println(Thread.currentThread().getName()+num);
  48.                 }

  49.         }
  50. }

  51. /*解析:
  52. //run()方法同步,拥有changeFlag()功能,且有wait()操作,这时候,即使有changeFlag().无法正常结束
  53. //因为Thread0执行,判断flag(true),进入wait状态,(重点)然后释放锁,thread1获得执行
  54. //thread1执行,判断flag(true),进入wait状态,此时thread0和thread1都处于wait(冻结)状态。
  55. //两个线程都是一开始就被wait了,还没来得及知道flag的值已经变化
  56. //也就是说,两个线程都已是wait状态,即使后来改变了flag的值,因为冻结在那里,无法动,仍无法正常结束

  57. 怎样才能正常结束?
  58. 方法一(自己想的,哈哈)
  59. 这时候就需要interrupt()强行唤醒wait。先打破wait状态,在改变flag的值就可以正常结束
  60. 在main线程中的这几行代码即可
  61.                         if(num++ == 6000)
  62.                         {
  63.                                 t1.interrupt();
  64.                                 t2.interrupt();
  65.                                 t.changeFlag();
  66.                                 break;
  67.                         }
  68. 方法二:
  69. 还是先打破wait状态,然后在catch中将flag直接赋值false
  70. run()里面:
  71.         catch (InterruptedException e)
  72.         {
  73.                 System.out.println(Thread.currentThread().getName()+"**exception");
  74.                 flag = false;
  75.         }
  76. mian线程:
  77.         if(num++ == 6000)
  78.         {
  79.                 t1.interrupt();
  80.                 t2.interrupt();
  81.                 break;
  82.         }
  83.         其实都一样,都是先打破wait,然后或者在catch处理的时候将置flag为false
  84.                                 或者在mian里面单独处理!
  85. */
复制代码


0 个回复

您需要登录后才可以回帖 登录 | 加入黑马