关于java:Java中创建线程的几种主流方式

继承Thread类

继承Thread类,并重写它的run办法,就能够创立一个线程了,当然线程是如何真正被启动,能够参考我之前的 为什么start办法能力启动线程,而run不行?

class ThinkThread extends Thread {
  @Override
  public void run() {
      System.out.println("think123");
  }
}

new ThinkThread().start();

复制代码

实现Runnable接口

 new Thread(() -> 
  System.out.println("实现了Runnable接口")
).start();
复制代码

结构Thread时传入Runnable类型的参数,也能够创立一个线程

通过线程池创立线程

// 提交 Runnable 工作
Future<?> submit(Runnable task);

// 提交 Callable 工作
<T> Future<T> submit(Callable<T> task);

// 提交 Runnable 工作及后果援用。 future.get()==result
<T> Future<T> submit(Runnable task, T result);
复制代码

Runnable类型的参数和Callable类型的参数不同之处在于Runnable 接口的 run() 办法是没有返回值的,所以 submit(Runnable task)这个办法返回的 Future 仅能够用来断言工作曾经完结了,相似于 Thread.join()。 而Callable是一个接口,它有一个call()办法,这个办法是有返回值的,这个能够通过 future.get() l获取工作执行后果

// 倡议手动创立线程池,这里只是为了举例
ExecutorService service = Executors.newFixedThreadPool(1);

Future future = service.submit(() -> "think123");

System.out.println(future.get());

复制代码

通过FutureTask创立线程

FutureTask继承了Runnable和Future接口,所以咱们能够将FutureTask对象作为工作提交到线程池执行,也能够间接被Thread执行,而且还能够获取到工作执行后果。

FutureTask task = new FutureTask(() -> "666");

Thread t1 = new Thread(task);
t1.start();;

// 阻塞main线程,直到t1执行实现
System.out.println(task.get());
复制代码

FutureTask的源码很简略,当执行run办法时,会将执行的后果保留在外部变量 outcome 中,即使是抛出了异样,此时也会将异样记录到outcome中。

当调用 get 办法时,如果还未执行实现,则会阻塞调用方。执行实现后会将失常的后果返回,如果call办法中抛出了异样,则将其封装成 ExecutionException 抛出。

总结

下面介绍了Java中罕用的创立线程执行的形式,能够发现,实际上都是通过 创立Thread来执行的,实际上也是能够算作一种,如果面试官问题,你能够先装一下说之后一种,而后峰回路转,给他说说为什么之后一种。

参考:《2020最新Java根底精讲视频教程和学习路线!》
链接:https://juejin.cn/post/692024…

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理