继承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 任务

Future submit(Callable task);

// 提交 Runnable 任务及结果引用。future.get()==result

Future 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来执行的,实际上也是可以算作一种,如果面试官问题,你可以先装一下说之后一种,然后峰回路转,给他说说为什么之后一种。

当然还有其他方式,比如TimerTask, Quartz Job但是实际上都是类似的。

在java中创建线程有几种办法_Java中创建线程的几种主流方式相关推荐

  1. JAVA中初始化线程的两种方法_java中最简单的方式新起一个线程

    启动一个线程 在一个方法中启动一个线程,有两种方法 第一种是让类实现Runable接口,这样的话编译器就会提示你实现里面的未实现的方法(就是run方法) 第二种是,现在方法中new一个线程,然后直接调 ...

  2. java多线程同步的四种方法_java中实现多线程的两种方法

    java多线程有几种实现方法,都是什么?同步有几种实java中多线程的实现方法有两种:1.直接继承thread类:2.实现runnable接口:同步的实现方法有五种:1.同步方法:2.同步代码块:3. ...

  3. java线程和进程的区别_Java中的线程和进程比较

    1.进程和线程的区别 通俗一点说,进程就是程序的一次执行,而线程可以理解为进程中的执行的一段程序片段. 用一点文词说就是,每个进程都有独立的代码和数据空间(进程上下文);而线程可以看成是轻量级的进程. ...

  4. Java中的几种引用类型_Java中的几种引用类型(转载)

    Java中的对象引用主要有以下几种类型: 1)强可及对象(strongly reachable): 可以通过强引用访问的对象,一般来说,我们平时写代码的方式都是使用的强引用对象,比如下边的代码段: S ...

  5. java 用户线程如何修改界面内容_java 加入一个线程、创建有响应的用户界面 。 示例代码...

    javajava 加入一个线程.创建有响应的用户界面 . 示例代码 来自thinking in java 4 21章 部分代码 目录21.2.11 package org.rui.thread.con ...

  6. java域的控制修饰符可分为_Java中的类和方法的修饰符

    java 中的类和方法的修饰符Java程序在定义类时,除了使用class关键字标识之外,还可以在class之前增加若干类的修饰符来修饰限定所定义的类的特性.类的修饰符分为访问控制符和非访问控制符两大类 ...

  7. 线程池参数详解_java中常见的六种线程池详解

    之前我们介绍了线程池的四种拒绝策略,了解了线程池参数的含义,那么今天我们来聊聊Java 中常见的几种线程池,以及在jdk7 加入的 ForkJoin 新型线程池 首先我们列出Java 中的六种线程池如 ...

  8. java年轻代和年老代默认比值_JAVA中的GC以及年轻代,年老代,持久代的认识

    java中我们常常谈论到垃圾回收机制,那么,垃圾回收机制又是什么呢?说到JVM调优,似乎很高大上,那么JVM调的都是那些数据呢?伊甸园区,幸存区,年轻代,年老代,持久代,每个词都熟悉又陌生,似乎很深奥 ...

  9. java中的equals拿什么鞋的_Java中==和equals方法

    Java程序中测试两个变量是否相等有两种方式:1.== :2.equals()方法 当使用==来判断两个变量是否相等时,如果两个变量是基本类型变量,且都是基本数值类型(不一定要求数据类型严格相同),则 ...

最新文章

  1. html+form+multipartform-data,表单 – 如何处理node.js中的multipart / form-data
  2. C++笔记——有关内存对齐
  3. html5 内嵌网页_如何分析并优化网页的性能?新梦想软件测试
  4. beginnersbook 数据库教程
  5. java判断safari_js代码判断浏览器种类IE、FF、Opera、Safari、chrome及版本
  6. 运维人员如何学好shell脚本编程
  7. ALSA声卡10_从零编写之数据传输_学习笔记
  8. C#连接mysql实例
  9. c++大作业--学籍管理系统--
  10. ADO.NET数据访问方式:SqlDataReader
  11. svn删除所有unversioned文件
  12. 项目启动会应该注意的几点
  13. Android App开发常用尺寸规范
  14. 电机控制初学入门资料_电机控制如何入门
  15. python 多行注释后可运行程序报错
  16. linux离线安装apr-util 报错,Linux 编译 apr-util 时报错
  17. gcc/g++ 优化标识 -O1 -O2 -O3 -Os -Ofast -Og的作用
  18. 电脑无法升级windows11的解决办法
  19. Mars3D\Cesium
  20. el-submenu中.el-submenu__title选中后背景色不变

热门文章

  1. Linux 12.10 ISO下载地址
  2. 发布一个域安全级别的无代码InfoPath表单作为文档库模版 (InfoPath 一)
  3. winform Combobox出现System.Data.DataRowView的解决的方法
  4. 解决Ubuntu 18.04中文输入法的问题
  5. 【实践】美团外卖图谱推荐比赛冠军经验分享:从多领域优化到AutoML框架
  6. 推荐系统系列教程之十六:深度和宽度兼具的融合模型
  7. windows下anaconda环境激活报错CommandNotFoundError: Your shell has not been properly configured to use ‘con
  8. Python实战从入门到精通第二十讲——调用父类方法
  9. 我为何选择Facebook广告
  10. 跨境电商ERP系统怎么使用?