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

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

 

传统方式创建线程:

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即可

 

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

第一种:你不是要先进行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方法

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值