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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© kane 中级黑马   /  2014-12-3 12:45  /  2036 人查看  /  14 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 kane 于 2014-12-3 13:26 编辑

/*
多线程练习
需求:在t1调用join()下,且t1的run方法里调用wait()无限等待,调用interrupt()方法唤醒主函数继续运行,并且与t2交替争夺资源

思路:我想通过flag的值的判断来唤醒主函数,从而达到t1继续等待,t2和主函数继续交替运行。
*/

class Res //判断值
{
        boolean flag=true;
}




class Dem implements Runnable
{
        private Res r;

        Dem(Res r)
        {
                this.r=r;
        }


        public synchronized  void run()//t1线程执行的方法
        {
                        
                        try
                        {
                                while(r.flag)
                                wait();                                
                                                
                        }
                        catch(InterruptedException e)
                        {
                                System.out.println(Thread.currentThread().getName()+"---t0--Exception---");
                                r.flag=false;
                        }

                        System.out.println(Thread.currentThread().getName()+"---t0---RUN----");
        }
}




class Cem implements Runnable  
{
        public synchronized void run()//t2线程执行的方法
        {
                for(int x=0;x<40;x++)
                {        
                        System.out.println(Thread.currentThread().getName()+"---t1-----"+x);
                }        
        
        }
}


class QDemo7
{
        public static void main(String[] args) throws Exception
        {
                Res r=new Res();

                Dem d=new Dem(r);

                Cem c=new Cem();
               
                Thread t1=new Thread(d);
                Thread t2=new Thread(c);


                t1.start();
                t2.start();

                for(int x=0;x<40;x++)
                {

                        System.out.println(Thread.currentThread().getName()+"---main-----"+x);        

                        t1.join();
                        Thread.currentThread().interrupt();
                }

                System.out.println("over");
        }
}


运行结果如图,执行到t1就无限等待了,求解

QDemo7.jpg (73.2 KB, 下载次数: 20)

QDemo7.jpg

点评

我也有类似的问题,同时也解决了我的疑惑  发表于 2014-12-5 10:09

14 个回复

倒序浏览
Thread.currentThread().interrupt();这句根本没执行到。这句在主线程里,而主线程在执行到ti.join()时就已经处于冻结状态了,只有t1执行完终止后,主线程才会被唤醒。要想手动清除主线程的冻结状态,必须在一个处于活跃状态的线程中执行interrupt()方法,这里可以使用t2线程。主线程被唤醒以后,再使用t1.interrupt()方法,清除t1线程的冻结状态,使程序结束。修改后代码如下:
  1. /*
  2. 多线程练习
  3. 需求:在t1调用join()下,且t1的run方法里调用wait()无限等待,调用interrupt()方法唤醒主函数继续运行,并且与t2交替争夺资源

  4. 思路:我想通过flag的值的判断来唤醒主函数,从而达到t1继续等待,t2和主函数继续交替运行。
  5. */

  6. class Res //判断值
  7. {
  8.         boolean flag=true;
  9. }




  10. class Dem implements Runnable
  11. {
  12.         private Res r;

  13.         Dem(Res r)
  14.         {
  15.                 this.r=r;
  16.         }


  17.         public synchronized  void run()//t1线程执行的方法
  18.         {
  19.                         
  20.                         try
  21.                         {
  22.                                 while(r.flag)
  23.                                 wait();                                
  24.                                                 
  25.                         }
  26.                         catch(InterruptedException e)
  27.                         {
  28.                                 System.out.println(Thread.currentThread().getName()+"---t1--Exception---");
  29.                                 r.flag=false;
  30.                         }

  31.                         System.out.println(Thread.currentThread().getName()+"---t1---RUN----");
  32.         }
  33. }




  34. class Cem implements Runnable  
  35. {

  36.                 private Thread main;
  37.                 public Cem(Thread main)
  38.                 {
  39.                         this.main = main;
  40.                 }
  41.         public synchronized void run()//t2线程执行的方法
  42.         {
  43.                 for(int x=0;x<40;x++)
  44.                 {        

  45.                         System.out.println(Thread.currentThread().getName()+"---t2-----"+x);
  46.                                                 main.interrupt();
  47.                 }        
  48.         
  49.         }
  50. }


  51. class QDemo7
  52. {
  53.         public static void main(String[] args) throws Exception
  54.         {

  55.                                 Thread main = Thread.currentThread();//获得主线程的引用。
  56.                 Res r=new Res();

  57.                 Dem d=new Dem(r);

  58.                 Cem c=new Cem(main);//将主线程传递给t2线程。
  59.                
  60.                 Thread t1=new Thread(d);
  61.                 Thread t2=new Thread(c);


  62.                 t1.start();
  63.                 t2.start();
  64.                                  try
  65.                  {
  66.                                         t1.join();
  67.                  }
  68.                  catch (InterruptedException e)
  69.                  {
  70.                                          System.out.println(Thread.currentThread().getName()+"---main--Exception---");
  71.                  }
  72.                 for(int x=0;x<40;x++)
  73.                 {

  74.                         System.out.println(Thread.currentThread().getName()+"---main-----"+x);        

  75.                     
  76.                                                
  77.                         //Thread.currentThread().interrupt();
  78.                 }

  79.                 System.out.println("over");
  80.                                 t1.interrupt();
  81.         }
  82. }
复制代码

点评

再次感谢你哈  发表于 2014-12-5 10:35
回复 使用道具 举报
李天富 发表于 2014-12-3 21:37
Thread.currentThread().interrupt();这句根本没执行到。这句在主线程里,而主线程在执行到ti.join()时就已 ...

非常感谢,终于成功实现了。:lol
回复 使用道具 举报
在需求:在t1调用join()下,且t1的run方法里调用wait()无限等待,调用interrupt()方法唤醒主函数继续运行,并且与t2交替争夺资源中。
main与t2交替争夺资源是指main线程运行一次,t2线程运行一次那样交替吗?
回复 使用道具 举报
Smart_lll 发表于 2014-12-6 09:31
在需求:在t1调用join()下,且t1的run方法里调用wait()无限等待,调用interrupt()方法唤醒主函数继续运行, ...

因为t2和 t1调用的方法不一样,所以t2的输出可以和主函数的输出同时进行
回复 使用道具 举报
kane 发表于 2014-12-6 09:58
因为t2和 t1调用的方法不一样,所以t2的输出可以和主函数的输出同时进行

这个我知道, 我想知道是交替执行吗?交替执行的意思是:
main线程
t2线程
main线程
t2线程
main线程
t2线程
...
这样交替?!?!
回复 使用道具 举报
kane 中级黑马 2014-12-6 18:14:30
7#
Smart_lll 发表于 2014-12-6 17:08
这个我知道, 我想知道是交替执行吗?交替执行的意思是:
main线程
t2线程

理想情况是这样的,不过内存CPU抢占资源的结果可能没有那么理想
回复 使用道具 举报
kane 发表于 2014-12-6 18:14
理想情况是这样的,不过内存CPU抢占资源的结果可能没有那么理想

恩恩,可以用一个lock两个condition搞定吧?!
回复 使用道具 举报
kane 中级黑马 2014-12-6 19:37:59
9#
Smart_lll 发表于 2014-12-6 19:35
恩恩,可以用一个lock两个condition搞定吧?!

对,说的没错:lol
回复 使用道具 举报

:lol:lol:lol
回复 使用道具 举报
我还是不明白啊

点评

多练习,多熟练,就会慢慢好起来的哈  发表于 2014-12-7 10:12
回复 使用道具 举报
kane 中级黑马 2014-12-7 10:07:32
12#

还不懂吗?
这里有源代码,你可以看看哈,希望对你有帮助
http://bbs.itheima.com/thread-155539-1-1.html
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马