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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© ∏艾力克斯※ 中级黑马   /  2013-11-21 12:02  /  1277 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 ∏艾力克斯※ 于 2013-11-22 21:46 编辑
  1. package manyThreadRun;

  2. /*
  3. * Stop方法已经过时。
  4. *
  5. * 如何停止线程?
  6. * 只有一种,run方法结束。
  7. * 开启多线程运行,运行代码通常是循环结构
  8. *
  9. * 只要控制住循环,就可以让run方法结束,也就是线程结束。
  10. *
  11. * 特殊情况:
  12. * 当线程处于冻结状态,
  13. * 就不会读取到标记,那么线程就不会结束。
  14. *
  15. * 当没有指定的方式让冻结的线程恢复到运行状态时,这是需要对冻结进行清除。
  16. * 强制让线程恢复到运行状态中来。这样就就可以操作标记让线程结束。
  17. *
  18. * Thread类提供该方法 interrupt();
  19. */

  20. class StopThread implements Runnable {
  21.         private boolean flag = true;

  22.         public synchronized void run() {
  23.                 while (flag) {
  24.                         try {
  25.                                 wait();
  26.                         } catch (InterruptedException e) {
  27.                                 System.out.println(Thread.currentThread().getName()
  28.                                                 + "....Exception");
  29.                                 flag = false;
  30.                         }
  31.                         System.out.println(Thread.currentThread().getName() + "....run");
  32.                 }
  33.         }

  34.         public void changeFlag() {
  35.                 flag = false;
  36.         }
  37. }

  38. public class StopThreadDemo {

  39.         /**
  40.          * @param args
  41.          */
  42.         public static void main(String[] args) {
  43.                 StopThread st = new StopThread();
  44.                 Thread t1 = new Thread(st);
  45.                 Thread t2 = new Thread(st);

  46.                 t1.start();
  47.                 t2.start();

  48.                 int num = 0;
  49.                 while (true) {
  50.                         if (num++ == 60) {
  51.                                 // st.changeFlag();
  52.                                 t1.interrupt();
  53.                                 t2.interrupt();
  54.                                 break;
  55.                         }
  56.                         System.out.println(Thread.currentThread().getName() + "...." + num);
  57.                 }
  58.                 System.out.println("over");
  59.         }
  60. }
复制代码
结果有三种:
1:over
Thread-0....Exception
Thread-0....run
Thread-1....Exception
Thread-1....run
2:over
Thread-0....Exception
Thread-0....run
3:over
Thread-1....Exception
Thread-1....run

为什么结果是三种情况呢?有点糊涂

评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1

查看全部评分

2 个回复

倒序浏览
因为你在run方法上加了一个synchronized。
第一种下情况,就是t1先执行wait了,t2再执行,wait了。main再执行,一口气执行完。t1和t2都进入catch。

其它两种情况,就是当t1,或t2拿到执行权后wait了。然后执行权被main拿到了。它一口气就执行完了。
这时,被wait的线程进入了catch,改变了flag,执行完。最后一个线程判断flag为flase变结束了。

为什么我还是3分?
回复 使用道具 举报
其实不止这三种情况,先给你解释一下这三种情况的原因:
因为主线程开启t1和t2两个线程的时候是按照先t1,后t2的顺序开启的;
但是哪一个线程先运行取决于CPU的快速切换,也就是线程运行的随机性,所以t1和t2哪一个先执行是不确定的。
t1和t2执行时都会进入wait(),所以谁先进入wait()也就不一定了。

而处于wait状态的等待线程是存在于线程池中的,当主函数interrupt的时候,t1和t2抢占资源的顺序也是随即的。
所以t1和t2谁先被唤醒也就不确定了。

解释一下你的第一种情况:
t1线程先运行进入wait状态,t2后进入wait状态。
等到主线程执行到num==60的时候开始终端wait状态的t1和t2,
t1和t2开始抢占CPU资源,当然在这t1先抢到,所以t1先执行,t2后执行。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马