暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Java多线程系列——实现多线程的两种方式

迅捷小莫 2021-09-02
117

继承Thread类

    1.自定义线程类 继承Thread
    2.重写run()方法,编写线程执行体
    3.创建线程对象,调用start()方法启动线程
      /**
      * 创建线程方式一:继承Thread类,重写run方法,调用start开启线程
      */
      public class Study1  extends Thread {


         // run 方法线程体
         @Override
         public void run() {
             for (int i = 0; i < 5; i++) {
                 System.out.println("我在学习java代码..." + i);
             }
         }


        // main 主线程
         public static void main(String[] args) {
             // 创建一个线程对象
             Study1 study1 = new Study1();
             // 调用start开启线程
             study1.start();
           
             for (int i = 0; i < 5; i++) {
                 System.out.println("我在学习多线程----" + i);
             }
         }
      }

      1

        思考:代码是从上往下执行吗?


        1、如上图 所示,根据代码是从上往下执行的,那如果你能读懂上面部分代码
        的话,应该可以得出,程序应该先输出:“我在学习java代码...”,然后才输
        出:“我在学习多线程----”,事实真的如此吗?


        2、小提莫已经帮你实践好了,我们接着往下康康...实际结果先打印了:“我在学
        习多线程----”,后输出了:“我在学习java代码...”。
          OutPut
           /*
          我在学习多线程----0
          我在学习多线程----1
          我在学习多线程----2
          我在学习多线程----3
          我在学习多线程----4
          我在学习java代码...0
          我在学习java代码...1
          我在学习java代码...2
          我在学习java代码...3
          我在学习java代码...4
          */

          2

            思考:调用start开启线程,比main线程执行更快?


            1、根据上面的结果,那意思调用start方法开启线程,比main线程执行更快?
            那如果需要验证这个,其实你只要把遍历数调大就可以很明显得出结论了~


            2、如下代码,实际结果太多,小提莫就不放答案了。想一起学习多线程的不防
            自己动手亲自看看答案,实际情况:“我在学习多线程----”,和“我在学习ja
            va代码...”会交替执行,意思就是线程开启后,2个线程是同时执行的,至于
            谁先执行,谁后执行,那得看CPU,因为这个是由CPU进行调度执行滴~


              /**
              * 创建线程方式一、继承Thread类,重写run方法,调用start开启线程
              */
              public class Study1 extends Thread {


              // run 方法线程体
              @Override
              public void run() {
              for (int i = 0; i < 200; i++) {
              System.out.println("我在学习java代码..." + i);
              }
              }


              // main 主线程
              public static void main(String[] args) {
              // 创建一个线程对象
              Study1 study1 = new Study1();
              // 调用start开启线程
              study1.start();

              for (int i = 0; i <1000; i++) {
              System.out.println("我在学习多线程----" + i);
              }
              }
              }

              实现Runnable接口

                1、实现 Runnable 接口
                2、重写run方法,编写线程体
                3、创建线程对象,调用start启动线程
                  /**
                  *  创建线程方式二:实现 Runnable 接口、 重写run方法,编写线程体、 创建线程对象,调用start启动线程
                  */
                  public class Study2 implements Runnable{


                     // run 方法线程体
                     @Override
                     public void run() {
                         for (int i = 0; i < 5; i++) {
                             System.out.println("我在学习java代码..." + i);
                         }
                     }


                     public static void main(String[] args) {


                         // 创建一个线程对象
                         Study2 study2 = new Study2();


                         // 创建线程对象,通过线程对象来开启线程, 这个也可以叫做 ---> 代理
                         // Thread thread = new Thread(study2);


                         // 调用start开启线程
                         // thread.start();


                         // 创建线程对象 调用start方法 简写
                         /**
                          * new Thread(Runnable对象)
                          * 为什么 参数是一个 Runnable对象,点击Thread 即可看到:源码如下
                          *
                          *    public Thread(Runnable target) {
                          *         init(null, target, "Thread-" + nextThreadNum(), 0);
                          *     }
                          */
                         new Thread(study2).start();


                         // main 主线程
                         for (int i = 0; i < 5; i++) {
                             System.out.println("我在学习多线程----" + i);
                         }
                     }
                  }


                  OutPut
                     /*
                  我在学习多线程----0
                  我在学习多线程----1
                  我在学习多线程----2
                  我在学习多线程----3
                  我在学习多线程----4
                  我在学习java代码...0
                  我在学习java代码...1
                  我在学习java代码...2
                  我在学习java代码...3
                  我在学习java代码...4
                  */

                  源码对比

                  # Thread:实际底层是继承了Runnable

                    public class Thread implements Runnable {
                       /* Make sure registerNatives is the first thing <clinit> does. */
                       private static native void registerNatives();
                       static {
                           registerNatives();
                       }
                       ... // 其余代码省略
                    }

                    # Runnable:底层只有一个run接口

                      @FunctionalInterface
                      public interface Runnable {
                         /**
                          * When an object implementing interface <code>Runnable</code> is used
                          * to create a thread, starting the thread causes the object's
                          * <code>run</code> method to be called in that separately executing
                          * thread.
                          * <p>
                          * The general contract of the method <code>run</code> is that it may
                          * take any action whatsoever.
                          *
                          * @see     java.lang.Thread#run()
                          */
                         public abstract void run();
                      }




                      结论

                        # 两者区别:(面试高频)
                        1、一个是继承Thread,一个是实现Runnable
                        2、Thread底层也是实现Runnable
                        3、java是单继承,多实现,所以更推荐实现Runnable
                        4、实现Runnable是通过线程对象来开启线程, 这个也可以叫做 ---> 代理
                        5、线程运行的代码块在run()方法里面,但是调用的时候不能直接调用run(),而是调用start()方法。
                        6、线程执行是同时执行,线程开启后不一定立即执行,具体执行是由CPU进行调度

                        你学费了吗,我的宝

                        扫码关注小提莫

                        微信号 | ya1kaikai


                        文章转载自迅捷小莫,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                        评论