线程创建

33 阅读1分钟

类关系

image.png

1、Thread

继承Thread类,并重写run方法

Demo:

class ThreadDemo1 extends Thread {
  @Override
  public void run() {
    log.info("{}", Thread.currentThread().getName());
  }
}

线程start后,会调用run方法。 Thread类信息:

class Thread implements Runnable {
       //thread 实现了 Runnable 接口
}

2、Runnable和Thread

Thread类的构造函数支持传入Runnable的实现类

Demo:

class RunnableThread implements Runnable {
    @Override
    public void run() {
        log.info("{}", Thread.currentThread().getName());
    }
}
​
private  void testRunnableThread() {
  Thread t2 = new Thread(new RunnableThread(), "t2");
  t2.start();
}

查看源码会发现Thread的构造方法会把Runnable接口的实现类赋值给target

/* What will be run. */
    private Runnable target;
//构造方法接受 Runnable 对象
public Thread(Runnable target) {
    init(null, target, "Thread-" + nextThreadNum(), 0);
}
//最终runnabel对象会赋值给 target    
private void init(ThreadGroup g, Runnable target, String name,
                  long stackSize, AccessControlContext acc,
                  boolean inheritThreadLocals) {
    this.target = target;
}    
//run 方法默认执行 target的run方法
public void run() {
    if (target != null) {
        target.run();
    }
}

3、Callable和Thread

  1. Callable和Runnable一样,也是一个函数式接口,二者的区别非常明显,Runnable中run方法没有返回值,Callable中的call方法有返回值(可以通过泛型约束返回值类型)。因此在需要获取线程执行的返回值时,可以使用Callable。
  2. 在Thread的构造函数中,并没有看到Callable,只有Runnable
  3. 此时需要一个可以提交Callable给Thread的类,这类就是FutureTask;FutureTask实现类Runnable接口。

总结来说 ,线程执行FutureTask 的run方法 ,run方法内执行 Callable的call方法 ,并把执行结果给到 FutureTask内的 Object outcome; 最终通过 FutureTask 的get方法获取结果

Demo:

     class CallableThread implements Callable<Integer> {
       @Override
       public Integer call() throws Exception {
         log.info("{}", Thread.currentThread().getName());
         return 1998;
       }
     }
    ​
    private FutureTask testCallableThread() throws InterruptedException, ExecutionException {
      FutureTask stringFutureTask = new FutureTask<>(new CallableThread());
      Thread t3 = new Thread(stringFutureTask, "t3");
      t3.start();
      //阻塞的获取线程结果
      final Object o = stringFutureTask.get();
      return stringFutureTask;
    }