线程(十一)两种传统传统方式创建:(thread、Runnable), 线程池方式ExcutorServicePool

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014252478/article/details/83587019

传统方式创建线程:

1、继承Thread类,重写run方法

2、实现Runnable接口,覆盖接口中的run方法,然后将接口实现扔给Thread

run方法探秘:

Thread源码中的run方法,如下:

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

由代码知道,run方法中是一个if判断,target不为空,就可以执行 target.run()

target是什么??

private Runnable target;

由代码知,target就是一个Runnable接口。

最后,进入Runnable代码:

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

Runnable中原来还是run方法;

我自己的理解为:Thread方法实现run方法要经历一个if语句的判断,直接不要if判断了,直接重写run; 而Runnable,直接调用重写run即可

扫描二维码关注公众号,回复: 3873427 查看本文章

总结:为什么创建线程有两种方式?

第一种:你不是要先进行if判断么?我现在不判断了,我把你的if干掉,我在run()方法中自己写代码,想干啥就干啥,即重写Thread中的run()方法,;

第二种:你不是要先进行if判断么?行,给你一个Runnable接口让你判断,但你还是得调用我Runnable中的run()方法啊,那我重写我Runnable中的run()方法不就行了! 

1、Thread创建线程(继承Thread)

(1)继承Thread,调用run方法

(2)start()开启线程

public static void main(String[] args){
   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();
}
 

2、Runnable创建线程(实现Runnable接口)

(1)实现Runnable接口,调用run方法

(2)start()开启线程

public static void main(String[] args){
    Thread thread2 = new Thread(new Runnable(){
           @Override
           public void run(){
              try(){
                  Thread.sleep(1000);
              } catch(Exception e){
                  e.printStackTrace();
              }
            System.out.println(Thread.currentThread().getName());  //让线程休息500毫秒
​
           }
      });
​
   thread2.start();
}

3、Thread和Runnable同时创建线程

public static void main(String[] args){
      new Thread(new Runnable(){//实现runnable接口
           @Override
           public void run(){
              try(){
                  Thread.sleep(1000);
              } catch(Exception e){
                  e.printStackTrace();
              }
            System.out.println("Runnable:" + Thread.currentThread().getName());  //让线程休息500毫秒
​
           }
      }){ //实现thread   
         @Override
         public void run(){
          try {
                    Thread.sleep(500);//让线程休息500毫秒
               } catch (InterruptedException e) {
                    e.printStackTrace();
               }
           System.out.println("Thread:" + Thread.currentThread().getName());//打印出当前线程名
         }
      }.start();
}
 

经过运行发现,执行的是Thread中的run方法。

总结:

执行start()后,肯定先在子类中找run()方法,找到了,父类的run()方法自然就被干掉了,所以会打印出Thread:,如果我们现在假设子类中没有重写run()方法,那么必然要去父类找run()方法,父类的run()方法中就得判断是否有Runnable传进来,现在有一个,所以执行Runnable中的run()方法,那么就会打印Runnable:出来。

4、ExcutorServicePool线程池方法,创建线程

private ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);
​
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");  //没有精确到毫秒
​
    public  void scheduledStatusNotify() {
        ScheduledFuture<?> future = pool.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
            ..........
           }
      });
    }

线程池的方式创建线程本质上还是通过第二种方法(Runnable接口),重写run方法

猜你喜欢

转载自blog.csdn.net/u014252478/article/details/83587019