FutureTask并发详解,通俗易懂
最近做项目,使用到了FutureTask和主线程并发,应用到实际中还是挺实用的,特在此总结一下。
有不对之处,忘各位多多指出。
package com.demo; import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask; public class FutureTaskTest { public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
long currentTimeMillis = System.currentTimeMillis();
FutureTask<String> future1 = new FutureTask<>(new MyTaskA());
new Thread(future1).start();// 一定要先开启线程,如果主线程在开启线程前调用,就没了并发的效果,可以自行测试
Thread.sleep(100);// 主线程耗时100ms
String r1 = future1.get();
System.out.println(r1);
System.err.println(i + "-----" + String.valueOf(System.currentTimeMillis() - currentTimeMillis) + "ms");
}
} static class MyTaskA implements Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(50);// 并发线程耗时50ms
return "testA";
}
} }
20-26行创建一个任务MyTaskA,实现的是Callable,主要是为了获取返回值(关于如何创建线程,这里就不在赘述);
11行创建FutureTask;
12行启动线程:此时任务MyTaskA就已经开始执行;
13行主线程执行耗时100ms的任务;
14行FutureTask获取返回值,该方法是会等待任务完成然后获取到返回值。
输出结果如下:
testA
0-----101ms
testA
1-----100ms
testA
2-----100ms
testA
3-----100ms
testA
4-----100ms
testA
5-----100ms
testA
6-----100ms
testA
7-----100ms
testA
8-----100ms
testA
9-----100ms
上面就是一个线程和主线程并发执行,下面再看一个两个线程和主线程并发,其实差别不大
package com.demo; import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask; public class FutureTaskTest { public static void main(String[] args) throws Exception{
for (int i = 0; i < 10; i++) {
long currentTimeMillis = System.currentTimeMillis(); FutureTask<String> futureA = new FutureTask<>(new MyTaskA());
FutureTask<String> futureB = new FutureTask<>(new MyTaskB());
new Thread(futureA).start();
new Thread(futureB).start(); Thread.sleep(100);
System.out.println(futureA.get()+"---"+futureB.get());
System.err.println(i+"-----"+String.valueOf(System.currentTimeMillis()-currentTimeMillis)+"ms");
}
}
static class MyTaskA implements Callable<String>{
@Override
public String call() throws Exception {
Thread.sleep(50);//并发线程耗时50ms
return "testA";
}
}
static class MyTaskB implements Callable<String>{
@Override
public String call() throws Exception {
Thread.sleep(50);
return "testB";
}
} }
执行结果如下
testA---testB
0-----103ms
testA---testB
1-----100ms
testA---testB
2-----100ms
testA---testB
3-----100ms
testA---testB
4-----100ms
testA---testB
5-----101ms
testA---testB
6-----100ms
testA---testB
7-----101ms
testA---testB
8-----100ms
testA---testB
9-----101ms
上面使用Thread启动的FutureTask,咱们也可以用线程池,代码如下
package com.demo; import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; public class FutureTaskTest { public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
long currentTimeMillis = System.currentTimeMillis();
ExecutorService executorService = Executors.newFixedThreadPool(2);
Future<String> futureA = executorService.submit(new MyTaskA());
Future<String> futureB = executorService.submit(new MyTaskB()); Thread.sleep(100);
System.out.println(futureA.get() + "---" + futureB.get());
System.err.println(i + "-----" + String.valueOf(System.currentTimeMillis() - currentTimeMillis) + "ms");
executorService.shutdown();//注意:用完之后一定要关闭线程池
}
} static class MyTaskA implements Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(50);// 并发线程耗时50ms
return "testA";
}
} static class MyTaskB implements Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(50);
return "testB";
}
} }
输出结果如下
testA---testB
0-----104ms
testA---testB
1-----101ms
testA---testB
2-----101ms
testA---testB
3-----101ms
testA---testB
4-----100ms
testA---testB
5-----102ms
testA---testB
6-----101ms
testA---testB
7-----101ms
testA---testB
8-----101ms
testA---testB
9-----101ms
FutureTask并发详解,通俗易懂的更多相关文章
- Reactor And Gev 详解 通俗易懂
reactor 详解 在类似网关这种海量连接, 很高的并发的场景, 比如有 10W+ 连接, go 开始变得吃力. 因为频繁的 goroutine 调度和 gc 导致程序性能很差. 这个时候我们可以考 ...
- java 并发 详解
1 普通线程和 守护线程的区别. 守护线程会跟随主线程的结束而结束,普通线程不会. 2 线程的 stop 和 interrupted 的区别. stop 会停止线程,但是不会释放锁之类的资源? in ...
- Microsoft SQL Server中的事务与并发详解
本篇索引: 1.事务 2.锁定和阻塞 3.隔离级别 4.死锁 一.事务 1.1 事务的概念 事务是作为单个工作单元而执行的一系列操作,比如查询和修改数据等. 事务是数据库并发控制的基本单位,一条或者一 ...
- EntityFramework Core解决并发详解
前言 对过年已经无感,不过还是有很多闲暇时间来学学东西,这一点是极好的,好了,本节我们来讲讲EntityFramewoek Core中的并发问题. 话题(EntityFramework Core并发) ...
- Java--集合框架详解
前言 Java集合框架的知识在Java基础阶段是极其重要的,我平时使用List.Set和Map集合时经常出错,常用方法还记不牢, 于是就编写这篇博客来完整的学习一下Java集合框架的知识,如有遗漏和错 ...
- 跟着阿里p7一起学java高并发 - 第19天:JUC中的Executor框架详解1,全面掌握java并发核心技术
这是java高并发系列第19篇文章. 本文主要内容 介绍Executor框架相关内容 介绍Executor 介绍ExecutorService 介绍线程池ThreadPoolExecutor及案例 介 ...
- 最强Java并发编程详解:知识点梳理,BAT面试题等
本文原创更多内容可以参考: Java 全栈知识体系.如需转载请说明原处. 知识体系系统性梳理 Java 并发之基础 A. Java进阶 - Java 并发之基础:首先全局的了解并发的知识体系,同时了解 ...
- 详解应对平台高并发的分布式调度框架TBSchedule
转载: 详解应对平台高并发的分布式调度框架TBSchedule
- C++11 并发指南三(Lock 详解)
在 <C++11 并发指南三(std::mutex 详解)>一文中我们主要介绍了 C++11 标准中的互斥量(Mutex),并简单介绍了一下两种锁类型.本节将详细介绍一下 C++11 标准 ...
随机推荐
- 功能代码(1)---通过Jquery来处理复选框
实现以下功能: 1:选中第一个复选框,那么下面所有的复选框都选中,去除选中第一个复选框,下面的都不选中 2:当点击全选按钮,上面足球.篮球.游泳.唱歌 全部选中 3:当点击全不选按钮,上面四个全部取消 ...
- Fleck For Web Socket
效果图 (前沿).WebSocket是一种基于TCP/IP通讯一种新的通讯协议,它实现了服务器和客户端双工通讯,允许服务器主动发送给客户端. (浏览器对Socket的支持) . 浏览器 支持情况 Ch ...
- 2018OKR年中回顾
一.2018OKR规划 目标1.温习专业基础知识 关键结果1.1 阅读<微积分之屠龙宝刀>+<微积分之倚天宝剑>,加深理解高等数学微积分的各种概念与公式(0.2 屠龙宝刀看了三 ...
- 使用MQ来保证分布式事务的最终一致性
前言 之前我们讨论了如何拆分一个订单下单的一个服务(https://www.cnblogs.com/linkstar/p/9610268.html) 从单体到微服务的拆分,当时我们只是对原来的整个服务 ...
- idea操作整理
前言 这篇记录一下,在idea使用的过程中一些加快开发效率的操作. live template  postfix 当使用一个数字或者一个参数按照以下写法会自动变成例子中的情况 100.for -&g ...
- DNS生产系统架构
主机名控制者: DNS 服务器地址:http://vbird.dic.ksu.edu.tw/linux_server/0350dns_1.php 安装博客:http://www.linuxidc.co ...
- 痞子衡嵌入式:第一本Git命令教程(7.1)- 清理之缓存(stash)
今天是Git系列课程第七课,上一课我们学会了查看Git本地历史提交,今天痞子衡要讲的是Git仓库的清理操作,一共4个命令,都是日常开发中非常实用的命令,掌握这4个命令,会让你有一种玩弄Git仓库于股掌 ...
- C语言之递归
递归例子如下: #include <stdio.h> /*函数声明*/ void digui(int n); int main() { ; digui(n); ; } void digui ...
- [MySQL] mysql int后面的数字与前导零填充
1.int或者tinyint等数值型字段的存储范围已经是固定的,和类型相关2.后面的数字只与显示有关,并且是在开启了zerofill前导零填充的前提下 3.显示的时候,在前面用0补全了 create ...
- JavaScript_01简介,基本语法,运算符
JavaScript(不是JScript和scriptease) 1.js分为内部引用和外部引用,无论是内部引用还是外部引用,都可以放在html(除标签内)的任意位置,但是定义的位置会影响执行的顺序 ...