java多线程学习(1) java线程Runnable,Thread,Callable,FutureTask

线程创建的方式

1.Thread对象

1.1 继承Thread对象

@Slf4j
public class MyThread extends Thread{
    
    
    @Override
    public void run() {
    
    
        // 线程要执行的内容
        log.debug("继承Thread方式");
    }
}

public class Test1 {
    
    
    public static void main(String[] args) {
    
    
        new MyThread().start(); // 启动线程
    }
}

1.2 直接使用Thread对象

public class Test1 {
    
    
    public static void main(String[] args) {
    
    
        Thread t = new Thread(){
    
    
            @Override
            public void run() {
    
    
                log.debug("线程执行");
            }
        };
        t.start();
    }
}

2.Runnable接口

public class MyThread implements Runnable{
    
    
    @Override
    public void run() {
    
    
        // 该线程执行内容
        System.out.println("线程执行");
    }
}

public static void main(String[] args) {
    
    
        MyThread myThread = new MyThread();
        Thread t1 = new Thread(myThread, "t1");
        t1.start();

        // jdk8 Lambda
        Thread t2 = new Thread(()->{
    
     System.out.println("t2执行");}, "t1");
        t2.start();

        Runnable runnable = ()->{
    
     System.out.println("t3执行"); };
        Thread t3 = new Thread(runnable, "t3");
        t3.start();
    }

3.Runnable和Thread的关系

Runnable的运行需要传入Thread中执行

      Runnable runnable = ()->{
    
     System.out.println("t3执行"); };
      Thread t3 = new Thread(runnable, "t3");
      t3.start();

点开Thread源码发现会把Runnable传个init方法

https://img-blog.csdnimg.cn/20201027204059703.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNTM5OTYy,size_16,color_FFFFFF,t_70#pic_center
发现init又传给另外一个init
在这里插入图片描述
该init方法中发现他又传给了自身的一个变量

在这里插入图片描述
发现在Thread类中的run()方法最终调用了这个Runnable的run方法

在这里插入图片描述

Runnable的run最终还是走的Thread的run,如果不重新run方法的情况下Thread的run方法会优先判断是否有Runnable传入,如果有那么就执行Runnable的run方法

3.Callable和FutureTask

FutureTask本身实现RunnableFuture

public class FutureTask<V> implements RunnableFuture<V>

RunnableFuture 又多继承了Runnable和Future

public interface RunnableFuture<V> extends Runnable, Future<V>

也就是说FutureTask也可以看做一个Runnable但是又强于Runnable
因为还继承了Future中的方法赋予了它获取线程运行结果的能力
在这里插入图片描述
Callable只是一个接口其call 和 Runnable的run方法性质差不多,都是线程要运行其中的代码,但call有返回值的泛型同时也能做异常的抛出,run方法就不具备异常也得内部自己消化

在这里插入图片描述

但我们运行代码的时候还是用的 start方法其还是去跑run方法,但发现我们这里并没有重写run方法而是一个call方法

在这里插入图片描述

点开FutureTask 类,发现其内部重写了run方法,当我们在start启动线程的时候该run方法会去调用其传入的Callable的call方法,并在这里做了异常的处理并在这个时候把值返回给FutureTask的set方法供get等方法的调用

在这里插入图片描述

值返回给变量outcome

在这里插入图片描述
调用get方法的时候调用其report方法
在这里插入图片描述
该方法的返回就是run方法调用call的值

在这里插入图片描述
注意
在这里插入图片描述
看到get方法有返回值,也就是说他会一直阻塞到线程异步的返回

猜你喜欢

转载自blog.csdn.net/qq_43539962/article/details/109300838
今日推荐