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 标准 ...
随机推荐
- Spring Security OAuth 2.0
续·前一篇<OAuth 2.0> OAuth 2.0 Provider 实现 在OAuth 2.0中,provider角色事实上是把授权服务和资源服务分开,有时候它们也可能在同一个应用中, ...
- dotnet core使用IO合并技巧轻松实现千万级消息推送
之前讲述过多路复用实现单服百万级别RPS吞吐,但在文中有一点是没有说的就是消息IO合并,如果缺少了消息IO合并即使怎样多路复用也很难达到百万级别的请求响毕竟所有应用层面的网络IO读写都是非常损耗性能的 ...
- 配置最新版LAMP环境
本篇文章讲解的是在centos7.3下配置 Apache2.4 + MySQL5.7 + PHP7.1.8 (如果是Nginx请跳过Apache流程继续往下看,所有流程本人已临床验证无数遍,绝无问题) ...
- python基础3--函数
1.函数定义 你可以定义一个由自己想要功能的函数,以下是简单的规则: 函数代码块以def关键词开头,后接函数标识符名称和圆括号(). 任何传入参数和自变量必须放在圆括号中间.圆括号之间可以用于定义参数 ...
- Android项目刮刮奖详解(四)
Android项目刮刮奖详解(三) 前言 上一期我们已经是完成了刮刮卡的基本功能,本期就是给我们的项目增加个功能以及美化一番 目标 增加功能 用户刮卡刮到一定程度的时候,清除遮盖层 在遮盖层放张图片, ...
- Mybatis框架基础支持层——反射工具箱之泛型解析工具TypeParameterResolver(4)
简介:TypeParameterResolver是一个工具类,提供一系列的静态方法,去解析类中的字段.方法返回值.方法参数的类型. 在正式介绍TypeParameterResolver之前,先介绍一个 ...
- Vue介绍
1.Vue的简介 Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架. Vue 只关注视图层, 采用自底向上增量开发的设计. Vue 的目标是通过尽可能简单的 AP ...
- 转:从输入url到显示网页发生了什么
在浏览器中输入url到显示网页主要包含两个部分: 网络通信和页面渲染 互联网内各网络设备间的通信都遵循TCP/IP协议,利用TCP/IP协议族进行网络通信时,会通过分层顺序与对方进行通信.分层由高到低 ...
- c或c++利用scanf无限输入并进行简单操作如比大小等
#include <iostream> using namespace std; int main() { ; ) //scanf返回值为int类型表示成功输入的数据数量个数 { if(n ...
- Android 手机连不上电脑
[个人经验] 给大家分享一下,最近Android开发中一个坑. 在Android开发中,有时会需要自己开发服务端,就需要连接自己的电脑. ①首先,我们得知道我们电脑的ip地址是多少: 开始菜单---- ...