Java Concurrency 01----Two Ways to Create Threads in Traditional Threads



  There are two ways to create threads in the traditional threading technology: one is to inherit the Threadclass and override the run()method ; the other is to implement Runnablethe interface, overwrite the run()methods in the Runnableinterface, and throw the implementation ofThread the interface . Most people probably know these two ways, but why is it OK to play this way? Let us analyze the ins and outs of these two methods in detail.

1. Demystifying run() in Thread

  We saw above that these two methods are related run()to methods, so let's take a look at what the methods Threadin the source code run()do:

@Override
public void run() {
    if (target != null) {
        target.run();
    }
}
  
  

      We can see that the run()method is very simple. There is only one ifstatement. If the target is not empty, the run()method of the target will be executed, otherwise it will not do anything. So what is the sacredness of the target? We click in to see:

    private Runnable target;
      
      

        The original target is the Runnable interface, let's click on Runnable to see:

      @FunctionalInterface
      public interface Runnable {
          public abstract void run();
      }
        
        

          There is only one method in Runnable, and it is also a run()method! Well, now go back to the run()method of the Thread class, if the target is not empty, that is, the Runnable interface is implemented, that is, the run()methods in Runnable are implemented, then we use the run()methods in the interface; if the target is empty, that is If the Runnable interface is not implemented, then we do nothing, that is, the thread disappears immediately after it is created.
          So here, everyone understands why there are two ways to create threads. The first: Don't you have to ifjudge first? I don't judge now, I will ifkill you, I run()will write the code in the method, I can do whatever I want, that is, rewrite the run()method in Thread, the second: don't you want to ifjudge first? Okay, I will give you a Runnable interface for you to judge, but you still have to call the run()methods in my Runnable, then I can just rewrite the run()methods in my Runnable!  
          After knowing the ins and outs, let's write an example for these two traditional methods.

        2. Creation method 1: Inherit the Thread class

          Create and start a thread in two steps:

        • Inherit the Threadclass and implement the run()method;
        • Call start()the method to start the thread.

        Since we only need to implement one run()method, we can use anonymous inner classes in java to implement it, as follows:

        public class TraditionalThread {
        
            public static void main(String[] args) {
        
                /********** 第一种方法:继承Thread类,覆写run()方法 **************/
                Thread thread1 = new Thread(){
        
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(500);//让线程休息500毫秒
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName());//打印出当前线程名
                    }
                };
                thread1.start();//开启线程
            }
        }
          
          

          3. Creation method 2: Implement the Runnable interface

            Create and start a thread in two steps:

          • Implement the Runnableinterface, and implement the run()method;
          • Call start()the method to start the thread.

          Since we only need to implement one run()method, we can also use anonymous inner classes in java to implement it, as follows:

          public class TraditionalThread {
          
              public static void main(String[] args) {
          
                  /********** 第二种方法:实现Runnable接口,扔给Thread **************/
                  Thread thread2 = new Thread(new Runnable() {
          
                      @Override
                      public void run() {
                          try {
                              Thread.sleep(500);
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                          System.out.println(Thread.currentThread().getName());
          
                      }
                  });
                  thread2.start();
              }
          }
            
            

            4. Use both methods at the same time

              如果有个哥们比较给力,他两种方式同时使用了,即:既实现了Thread类中的run()方法,又给Thread扔了一个实现了run()方法的Runnable。如下所示:

            public class TraditionalThread {
            
                public static void main(String[] args) {
                    //这哥们的代码写的比较给力
                    new Thread(new Runnable() {
            
                        @Override
                        public void run() {
                            try {
                                Thread.sleep(500);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            System.out.println("Runnable:" + Thread.currentThread().getName());
                        }
                    }){
            
                        @Override
                        public void run() {
                            try {
                                Thread.sleep(500);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            System.out.println("Thread:" + Thread.currentThread().getName());
                        }
            
                    }.start();
                }
            
            }
              
              

                现在又会执行哪个呢?我们运行一下上面的程序就会发现,它会打印出Thread的信息,所以运行的是Thread的run()方法,知道结论了,但是为啥呢?
                从面向对象的思想去考虑:上面一段代码其实是新new了一个对象(子对象)继承了Thread对象(父对象),在子对象里重写了父类的run()方法,父对象中扔了个Runnable进去,父对象中的run()方法就是最初的带有if判断的run()方法。
                好了,现在执行start()后,肯定先在子类中找run()方法,找到了,父类的run()方法自然就被干掉了,所以会打印出Thread:,如果我们现在假设子类中没有重写run()方法,那么必然要去父类找run()方法,父类的run()方法中就得判断是否有Runnable传进来,现在有一个,所以执行Runnable中的run()方法,那么就会打印Runnable:出来。
                   
               




                传统的线程技术中有两种创建线程的方式:一是继承Thread类,并重写run()方法;二是实现Runnable接口,覆盖接口中的run()方法,并把Runnable接口的实现扔给Thread。这两种方式大部分人可能都知道,但是为什么这样玩就可以呢?下面我们来详细分析一下这两种方法的来龙去脉。

              Guess you like

              Origin http://10.200.1.11:23101/article/api/json?id=326877882&siteId=291194637