黑马程序员技术交流社区

标题: 我哪想错了?视频的多线程疑问 [打印本页]

作者: 黑马王振宇    时间: 2013-1-11 20:10
标题: 我哪想错了?视频的多线程疑问
本帖最后由 黑马王振宇 于 2013-1-11 21:28 编辑
  1. class ThreadTest
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 new Thread()
  6.                 {
  7.                         public void run()
  8.                         {
  9.                                 for(int x=0; x<100; x++)
  10.                                 {
  11.                                         System.out.println(Thread.currentThread().getName()+"....."+x);
  12.                                 }
  13.                         }
  14.                 }.start();

  15.                 for(int x=0; x<100; x++)
  16.                 {
  17.                         System.out.println(Thread.currentThread().getName()+"....."+x);
  18.                 }

  19.                 Runnable r  = new Runnable()
  20.                 {
  21.                         public void run()
  22.                         {
  23.                                 for(int x=0; x<100; x++)
  24.                                 {
  25.                                         System.out.println(Thread.currentThread().getName()+"....."+x);
  26.                                 }
  27.                         }
  28.                 };
  29.                 new Thread(r).start();
  30.         }
  31. }
复制代码
以上是代码,视频具体位置:黑马程序员_毕向东_Java基础视频教程第12天-10-多线程(优先级&yield方法).avi  13分52秒处
毕老师问:“大家几个线程啦?3个了吧?他们仨是不可以能达到同时运行?明白了吧?”
我的疑问:这里毕老师说3个线程能同时运行,可是真的能同时运行么?Thread-0和main同步,但是Thread-1必须在main的for循环运行结束后才能start,
main和Thread-1不能交替打印,每次运行结果都是main....99之后才出现Thread-1....0然后结束,也就是说main和Thread-1不能同步,请问我哪想错了?
作者: 陈丽莉    时间: 2013-1-11 20:58
本帖最后由 陈丽莉 于 2013-1-11 21:01 编辑

      我认真看了一下毕老师那段的视频,是这样的,老师主要讲的是可以用单独的类封装线程和你贴的代码这样,匿名类封装。重点是匿名类可以有这两种方法,所以就着那三个循环就演示了一下,并没有整合这个小代码。毕老师前面也讲过,当要开启主线程外的其他线程时,是要先开启其他线程,再运行主函数中的循环代码,这样才能一起执行的,这点在其他线程的例子中和前面的视频中都有体现。
    当将两个匿名类的线程都放在主函数循环前开启时,只要将循环的临界值增大一些,就可以看到三个线程交替运行了。
    我这里改成了300,代码如下:
public class ThreadTest
{
        public static void main(String[] args)
       {
               new Thread()
              {
                       public void run()
                      {
                               for(int x=0; x<300; x++)
                             {
                                      System.out.println(Thread.currentThread().getName()+"....."+x);
                               }
                     }
              }.start();

               Runnable r  = new Runnable()
              {
                       public void run()
                       {
                               for(int x=0; x<300; x++)
                              {
                                      System.out.println(Thread.currentThread().getName()+"....."+x);
                               }
                      }
               };
                new Thread(r).start();

               for(int x=0; x<300; x++)
               {
                      System.out.println(Thread.currentThread().getName()+"....."+x);
               }
       }
}
运行结果如图:

000000000.png (6.58 KB, 下载次数: 39)

000000000.png

作者: 肖志锋    时间: 2013-1-11 21:02
本帖最后由 肖志锋 于 2013-1-11 21:06 编辑

你确实是想错了,所谓的多线程,是说同时运行,但这个同时不是说在一个时间点上同时运行,而是说在一个时间段上面每个线程都具有执行资格,但具体到每一个时间点上面,就只能有一个线程在执行,当然我说的是单核的CPU,因为cpu随机的给具有执行资格的线程执行权,只有具有执行权的线程才能执行他自己的代码,才会让cpu跑他。具体到你这个程序里面呢,有3个线程,主线程,Thread的子类线程,参数是继承Runnable接口的线程。为什么要在每个线程里面打印100呢,其实就是想每个线程跑得久一点,因为cpu分配执行权,也就是分配的时间片那段时间内,不让这个线程跑完,这样就能实现我们想要的结果,也就是3个线程会交叉执行,表现出来就是打印出来是交叉的结果。当然咯,如果你电脑太快,一下就跑完了,那你就循环久一点,或者sleep一下嘛。
作者: 黑马王振宇    时间: 2013-1-11 21:14
陈丽莉 发表于 2013-1-11 20:58
我认真看了一下毕老师那段的视频,是这样的,老师主要讲的是可以用单独的类封装线程和你贴的代码这样 ...

哦,你说的我懂了,知识点是匿名封装类,而也确实是3个线程同时执行了,只是没法看效果,你的代码调了顺序看的效果会更明显,跟据你说的我可以理解为,如果main结束了那么他就没法开启Thread-1了,在main开启新线程到main结束这个过程中处于3线程同步(即使开启后到结束过程中没有执行代码块),所以3个线程同步了,ok完全明白了,谢谢你耐心并详细的解答。
作者: 黑马王振宇    时间: 2013-1-11 21:32
肖志锋 发表于 2013-1-11 21:02
你确实是想错了,所谓的多线程,是说同时运行,但这个同时不是说在一个时间点上同时运行,而是说在一个时间 ...

哦,哥们你说这些我明白,你没明白我提的问题的意思~不过还是要谢谢你~
作者: 肖志锋    时间: 2013-1-11 21:51
本帖最后由 肖志锋 于 2013-1-11 22:00 编辑
黑马王振宇 发表于 2013-1-11 21:32
哦,哥们你说这些我明白,你没明白我提的问题的意思~不过还是要谢谢你~

刚才看了你前面的回复,我不知道我的理解是不是对的,你说的另外两个线程在主线程结束之前必须要开启。这话有点饶,如果你的意思是主线程的结束和开启其他线程是分开两码事话,我觉得有点不对了,因为这个两个线程其实就是主线程开启的,也就是那个Start的方法是主线程调用的,主线程结束前必然已经开启其他线程了,这两是一体的。而生成的两个线程执行了什么呢?他们只是在执行他们自己run方法。那么你说的“跟据你说的我可以理解为,如果main结束了那么他就没法开启Thread-1了”这话在你这里就完全错误了,因为Thread1和2就是你主线程自己开启的 ,他结束前必然已经开启,要不你还没开启他们怎么能够自己结束呢?这本来就是主线程的工作。
额···总结起来,开启线程是main线程自己的事,不可能说不做就结束了,除非异常什么的。跟主线程那个循环在哪里一毛钱关系都没有,只跟时间片的分配以及循环的次数有关。
作者: 黑马王振宇    时间: 2013-1-11 22:23
肖志锋 发表于 2013-1-11 21:51
刚才看了你前面的回复,我不知道我的理解是不是对的,你说的另外两个线程在主线程结束之前必须要开启。这 ...

哥们你别郁闷了,咱俩说的不是一回事,请不要质疑我对多线程概念的理解,另外也请你多看看我说的那段视频,以及我提问的意思。我说的另外两个线程在主线程结束之前必须要开启这句话没错,这里的开启就是start,不是Thread对象,不改代码的话,main结束之前不start另外两个线程没法同步~
如果main结束了那么他就没法开启Thread-1了这句话没错~main中没调用Thread-1的start方法怎么能让main和Thread-1同步呢?
此问题已经解决,你楼上的那位说的:当要开启主线程外的其他线程时,是要先开启其他线程,再运行主函数中的代码是解决这问题的关键。
作者: 肖志锋    时间: 2013-1-11 22:40
黑马王振宇 发表于 2013-1-11 22:23
哥们你别郁闷了,咱俩说的不是一回事,请不要质疑我对多线程概念的理解,另外也请你多看看我说的那段视频 ...

这郁闷什么啊,我是好像有点没整到点子上了,不过看了你现在这个说法,我好像发现自己有些地方更明白了,挺好,讨论下更加深理解,学习嘛 ,不就这样。




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