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

java多线程--1

  • 线程创建的方式
    • 1.Thread对象
      • 1.1 继承Thread对象
      • 1.2 直接使用Thread对象
    • 2.Runnable接口
    • 3.Runnable和Thread的关系
    • 3.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方法

java多线程(1) java线程Runnable,Thread,Callable,FutureTask_第1张图片
发现init又传给另外一个init
java多线程(1) java线程Runnable,Thread,Callable,FutureTask_第2张图片
该init方法中发现他又传给了自身的一个变量

java多线程(1) java线程Runnable,Thread,Callable,FutureTask_第3张图片
发现在Thread类中的run()方法最终调用了这个Runnable的run方法

java多线程(1) java线程Runnable,Thread,Callable,FutureTask_第4张图片

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中的方法赋予了它获取线程运行结果的能力
java多线程(1) java线程Runnable,Thread,Callable,FutureTask_第5张图片
Callable只是一个接口其call 和 Runnable的run方法性质差不多,都是线程要运行其中的代码,但call有返回值的泛型同时也能做异常的抛出,run方法就不具备异常也得内部自己消化

java多线程(1) java线程Runnable,Thread,Callable,FutureTask_第6张图片

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

java多线程(1) java线程Runnable,Thread,Callable,FutureTask_第7张图片

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

java多线程(1) java线程Runnable,Thread,Callable,FutureTask_第8张图片

值返回给变量outcome

java多线程(1) java线程Runnable,Thread,Callable,FutureTask_第9张图片
调用get方法的时候调用其report方法
java多线程(1) java线程Runnable,Thread,Callable,FutureTask_第10张图片
该方法的返回就是run方法调用call的值

java多线程(1) java线程Runnable,Thread,Callable,FutureTask_第11张图片
注意
java多线程(1) java线程Runnable,Thread,Callable,FutureTask_第12张图片
看到get方法有返回值,也就是说他会一直阻塞到线程异步的返回

你可能感兴趣的:(笔记,java,多线程)