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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 何仕映 中级黑马   /  2013-3-23 17:38  /  1616 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 何仕映 于 2013-3-24 10:40 编辑

在看到毕老师第十二天停止线程后自己敲代码时,忘记给run()方法上锁了,但是为什么不上锁,线程就不进入冻结状态呢?
请各位大哥大姐给我分析一下,代码的执行过程。
  1. class StopThread implements Runnable
  2. {
  3.         private boolean flag =true;
  4.         public synchronized void run()//为什么这里不加锁为什么线程就不能进入冻结状态呢?
  5.         {
  6.                 while(flag)
  7.                 {
  8.                         try
  9.                         {
  10.                                 wait();
  11.                         }
  12.                         catch (InterruptedException e)
  13.                         {
  14.                                 System.out.println("中断异常");
  15.                         }        
  16.                         System.out.println(Thread.currentThread().getName()+"....run");
  17.                 }
  18.         }
  19.         public void changeFlag()
  20.         {
  21.                 flag = false;
  22.         }
  23. }

  24. class  StopThreadDemo
  25. {
  26.         public static void main(String[] args)
  27.         {
  28.                 StopThread st = new StopThread();
  29.                
  30.                 Thread t1 = new Thread(st);
  31.                 Thread t2 = new Thread(st);

  32.                 t1.start();
  33.                 t2.start();

  34.                 int num = 0;

  35.                 while(true)
  36.                 {
  37.                         if(num++ == 60)
  38.                         {
  39.                                 st.changeFlag();
  40.                                 break;
  41.                         }
  42.                         System.out.println(Thread.currentThread().getName()+"......."+num);
  43.                 }
  44.                 System.out.println("over");
  45.         }
  46. }
复制代码

点评

如果问题未解决,请继续追问回复者,如果问题已经解决,请将分类改为“已解决”,谢谢  发表于 2013-3-24 07:33

评分

参与人数 1技术分 +1 收起 理由
贾文泽 + 1

查看全部评分

8 个回复

倒序浏览
本帖最后由 blackcaismine 于 2013-3-23 18:00 编辑

额,我试了一下你的代码,是可以终止的,但是运行过程中会产生一个问题就是有IllegalMonitorStateException异常。
IllegalMonitorStateException是当前的线程不是此对象监视器的所有者时抛出的异常,也就是说在线程1仍旧指向run方法内使用wait()的时候,线程2
试图插入进来使用wait()产生了错误。所以加上了锁就可以防止这样的情况发生。
但是不加锁即便会产生问题,这段代码仍旧能够停止。。

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
blackcaismine 发表于 2013-3-23 17:59
额,我试了一下你的代码,是可以终止的,但是运行过程中会产生一个问题就是有IllegalMonitorStateException ...

我知道仍能停止,我问的是为什么不加锁,就是上面代码注释的那一行,为什么不加synchronized,线程就不进入冻结状态,加上同步以后就进入冻结状态。按理说加不加锁,都会进入冻结状态的啊。麻烦你指点一下,谢谢。
回复 使用道具 举报
本帖最后由 blackcaismine 于 2013-3-23 19:05 编辑
何仕映 发表于 2013-3-23 18:45
我知道仍能停止,我问的是为什么不加锁,就是上面代码注释的那一行,为什么不加synchronized,线程就不进 ...

按我的理解是,不加同步,一个线程使用wait()后,另一个线程再用wait()根本不起作用,直接报异常,所以无法冻结。
回复 使用道具 举报
blackcaismine 发表于 2013-3-23 19:04
按我的理解是,不加同步,一个线程使用wait()后,另一个线程再用wait()根本不起作用,直接报异常,所以无 ...

就算只有一个起作用,那也应该程序结束也不会结束啊。可程序还是结束了啊?
回复 使用道具 举报
本帖最后由 blackcaismine 于 2013-3-23 19:34 编辑
何仕映 发表于 2013-3-23 19:07
就算只有一个起作用,那也应该程序结束也不会结束啊。可程序还是结束了啊? ...

抱歉,刚刚我也不太清楚为什么会这样。
于是我将t2线程注释掉,然后未加同步进行执行,
结果发现,即便只有一个线程访问未加锁的wait() 也会出现异常,因此无效。
你可以试验下,如果这样的话那么就可以解释为何两个线程都不会冻结了。
回复 使用道具 举报
filter 中级黑马 2013-3-23 19:43:33
7#
                while(true)

                {

                        if(num++ == 60)

                        {

                                st.changeFlag();

                                break;

                        }

                        System.out.println(Thread.currentThread().getName()+"......."+num);

                }
还是这段代码出的问题,当线程t1或t2,开始执行,调用run方法,进入等待,
由于没有加锁,这个时候主线程可能会抢到执行权,开始执行主线程while循环部分,
所以抛出IllegalMonitorStateException,主线程和自定义线程的锁不一样
run方法加了同步之后,t1,t2两个线程执行不会受干扰

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
李志阳 发表于 2013-3-23 19:43
while(true)

                {

不是吧,主线程执行while循环怎么会抛出IllegalMonitorStateException??
wait()方法并没有被主线程访问到。
回复 使用道具 举报
filter 中级黑马 2013-3-23 20:33:58
9#
blackcaismine 发表于 2013-3-23 19:54
不是吧,主线程执行while循环怎么会抛出IllegalMonitorStateException??
wait()方法并没有被主线程访问 ...

嗯,刚吃饭回来,刚刚也觉得不太对劲,不好意思
还是wait方法出的问题,没有制定锁就会抛出IllegalMonitorStateException
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马