一、实现Runnable接口

public classRunnableDemo implements Runnable {public voidrun() {try{

Thread.sleep(100);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println("in runnable demo");

}

}

非阻塞调用

public static void main(String[] args) throwsException {

Thread runnableThread= new Thread(newRunnableDemo());runnableThread.start();

System.out.println("in main");

}

输出结果

in main

in runnable demo

可以看到线程的运行没有阻塞当前线程

阻塞调用

public static void main(String[] args) throwsException {

Thread runnableThread= new Thread(newRunnableDemo());

runnableThread.start();

runnableThread.join();

System.out.println("in main");

}

输出结果

in runnable demo

in main

Join会阻塞当前线程,一直等待自定义线程才返回。

二、实现Callable接口

在Runnable的例子中,Runnable接口有一个很大的缺陷就是run方法没有返回值定义,主线程无法获取到线程执行的结果。这个时候就需要Callable接口。

public class CallableDemo implements Callable{public CallableDtocall() throwsException {try{

Thread.sleep(100);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println("in callable demo");return new CallableDto(1);

}

}classCallableDto {private intid;public CallableDto(intid) {this.id =id;

}public intgetId() {returnid;

}public void setId(intid) {this.id =id;

}

}

非阻塞调用

public static void main(String[] args) throwsException {

ThreadPoolExecutor executor= (ThreadPoolExecutor) Executors.newFixedThreadPool(10);

Future future = executor.submit(newCallableDemo());

System.out.println("in main");

}

输出结果,如下所示,新启动的线程没有阻塞当前线程

in main

in callable demo

阻塞调用,且拿到结果

public static void main(String[] args) throwsException {

ThreadPoolExecutor executor= (ThreadPoolExecutor) Executors.newFixedThreadPool(10);

Future future = executor.submit(newCallableDemo());

CallableDto callableDto=future.get();

System.out.println("in main");

System.out.println("id from callable is " +callableDto.getId());

}

get方法首先会阻塞主线程,等待当前线程执行结束才返回,且返回线程的执行结果。

三、CompletableFuture方式

CompletableFuture是jdk1.8引入的api,做了进一步的封装,用户线程无需实现Callable接口也能启动,且能够返回用户线程的执行结果

public static CompletableFuture supplyAsync(Supplier supplier, Executor executor)

一个没有实现Callable的普通方法

public classCompletableFutureDemo {publicCompletableFutureDemoDto action() {try{

Thread.sleep(100);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println("in CompletableFutureDemo ");return new CompletableFutureDemoDto(1);

}

}classCompletableFutureDemoDto {private intid;public CompletableFutureDemoDto(intid) {this.id =id;

}public intgetId() {returnid;

}public void setId(intid) {this.id =id;

}

}

非阻塞调用

public static void main(String[] args) throwsException {

ThreadPoolExecutor executor= (ThreadPoolExecutor) Executors.newFixedThreadPool(10);

CompletableFuture future = CompletableFuture.supplyAsync(() ->{return newCompletableFutureDemo().action();

}, executor);

System.out.println("in main");

}

执行结果,可以看到,主线程没有被阻塞

in main

in CompletableFutureDemo

阻塞调用且获取结果

public static void main(String[] args) throwsException {

ThreadPoolExecutor executor= (ThreadPoolExecutor) Executors.newFixedThreadPool(10);

CompletableFuture future = CompletableFuture.supplyAsync(() ->{return newCompletableFutureDemo().action();

}, executor);

CompletableFutureDemoDto demoDto=future.join();

System.out.println("in main");

System.out.println("id from demoDto is " +demoDto.getId());

}

执行结果,主线程一直被阻塞,一直等到用户线程返回

in CompletableFutureDemo

in main

id from demoDto is1

java启动100线程_Java启动新线程的几种方式(Runnable、Callable、CompletableFuture)相关推荐

  1. java new thread参数_java开启新线程并传参的两种方法

    一.继承Thread类 步骤: 1):定义一个类A继承于Java.lang.Thread类. 2):在A类中覆盖Thread类中的run方法. 3):我们在run方法中编写需要执行的操作:run方法里 ...

  2. java 连接池配置_java数据库连接池配置的几种方式

    关于java数据库连接池配置的几种方式 今天遇到了关于数据源连接池配置的问题,发现有很多种方式可以配置,现总结如下,(已Mysql数据库为例) 一,Tomcat配置数据源: 方式一:在WebRoot下 ...

  3. java类初始数组_java中数组初始化的三种方式是什么

    java中数组初始化的三种方式是:1.静态初始化,如[int a[] = {2, 0, 1, 9, 2020}]:2.动态初始化,如[int[] c = new int[4]]:3.默认初始化,如[i ...

  4. java调用restful接口_Java调用RESTful接口的几种方式

    前端一般通过Ajax来调用,后端调用的方式还是挺多的,比如HttpURLConnection,HttpClient,Spring的RestTemplate 服务端代码如下: 服务端接口请求的URL:h ...

  5. java如何实现多线程_Java中实现多线程的两种方式

    /** * 使用Thread类模拟4个售票窗口共同卖100张火车票的程序 * * 没有共享数据,每个线程各卖100张火车票 * * @author jiqinlin * */public class  ...

  6. java hashmap遍历顺序_Java中HashMap遍历的两种方式

    第一种: Map map =  HashMap(); Iterator iter = map.entrySet().iterator(); (iter.hasNext()) { Map.Entry e ...

  7. java 数组 源码_Java数组转List的三种方式及对比

    来源:https://s.yam.com/6wu6n 前言: 本文介绍Java中数组转为List三种情况的优劣对比,以及应用场景的对比,以及程序员常犯的类型转换错误原因解析. 一.最常见方式(未必最佳 ...

  8. java 如何初始化数组_java中初始化数组的三种方式分别是什么

    三种初始化方式: 1.静态初始化:创建+赋值 2.动态初始化:先创建再赋值 3.默认初始化:创建之后若不赋值则会被赋对应数据类型的默认值 (视频教程推荐:java视频) 我们来看一下具体代码:publ ...

  9. java获取文件后缀_Java获取文件后缀的两种方式

    在对文件进行操作的时候,我们经常需要用到文件的后缀.但是Java API中并没有提供获取文件后缀的方法.下面的工具方法可以帮助我们实现这个目的. 方法1 代码示例: package org.4spac ...

  10. java 读取文件 效率_Java 逐行读取文本文件的几种方式以及效率对比

    前言 上周负责的模块中需要逐行读取文件内容, 写完之后对程序执行效率不太满意, 索性上网查了一下 Java 逐行读取文件内容的各种方法, 并且简单地比对了一下执行效率. 在此记录, 希望能够帮到有需要 ...

最新文章

  1. 高频一线大厂 Python 面试题:算法+爬虫+数据处理+基础
  2. 收藏:asp.net
  3. sqlite数据库实现字符串查找的方法(instr,substring,charindex替代方案)
  4. AUTOSAR从入门到精通100讲(二十八)-AutoSar之CAN网络管理
  5. 矩阵 计算机应用,《计算机视觉算法:基于OpenCV的计算机应用开发》 —3.3 元素级矩阵操作...
  6. 2015-11-16
  7. poj Ancient Cipher 古代密码
  8. tornado(五)
  9. linux下载安装禅道
  10. 数值分析复习(六)——常微分方程数值解法
  11. 如何通过搜索计算机共享打印机驱动程序,怎么解决连接共享打印机时“找不到驱动程序”...
  12. 我国的居民身份证号码,由由十七位数字本体码和一位数字校验码组成。请定义方法判断用户输入的身份证号码是否合法,并在主方法中调用方法测试结果。规则为:号码为18位,不能以数字0开头,前17位只可以是数字,
  13. 技术QA:如何找回丢失的证书模板或将独立CA转换成企业CA?
  14. mysql编译器安卓版_手机在线编译器
  15. LNMP 平台的 redis 对接安装
  16. 【论文写作——投稿和审稿】
  17. 亚信实习——初来乍到
  18. 计算机理论导引 试卷,计算机理论导引实验报告_CFG是P成员.doc
  19. 【520表白日】程序员如何表白吗?程序员表白教程送给你!
  20. 拓商:拼多多客服回复慢,到底应该怎么解决?

热门文章

  1. pyecharts line_base绘图只有坐标轴,数据不再数轴上显示
  2. docwizard c++程序文档自动生成工具_如何开发一个基于 TypeScript 的工具库并自动生成文档
  3. Spark算子:RDD基本转换操作–coalesce、repartition
  4. C++/Cli中事件对象处理函数的添加与删除
  5. 减少系统资源占用的15个CSS常识
  6. 词法分析(4)---NFA与DFA的转化
  7. eclipse安装SVN插件报错Unable to connect
  8. main() 函数解析(一)——Linux-0.11 剖析笔记(六)
  9. 代码段间转移控制时的特权级检查(JMP/CALL)——《x86汇编语言:从实模式到保护模式》读书笔记28
  10. Docker搭建Nacos1.3+Seata1.4+MySQL8分布式事务(服务端)