关键词:
1 介绍
接本专题博客之 系统运维系列 之java中实现多线程的方式
上篇博客提到多线程使用的4种方式,分别是:
实现方式1:继承Thread类,重写该类的run方法;
实现方式2:实现Runnable接口,并重写该接口的run()方法;
实现方式3:通过Callable和FutureTask创建线程;
Callable接口实际上是属于Executor框架中的功能类,Callable接口与Runnable接口的功能类似,但提供了比Runnable更加强大的功能;Callable可以在任务结束的时候提供一个返回值,Runnable无法提供这个功能。
实现方式4:通过线程池创建线程。
方法3和4可以组合起来一起使用,首先创建线程池,然后利用FutureTask对象的get()来获取子线程执行结束的返回值用于后续程序的处理。
2 核心代码实现
//仅使用方法3实现
class MyCallable implements Callable<Integer>
private int i = 0;
// 与run()方法不同的是,call()方法具有返回值
@Override
public Integer call()
int sum = 0;
for (i=0; i < 10; i++)
System.out.println(Thread.currentThread().getName() + " " + i);
sum += i;
return sum;
public class ThreadTest
public static void main(String[] args)
Callable<Integer> myCallable = new MyCallable(); // 创建MyCallable对象
FutureTask<Integer> ftask = new FutureTask<Integer>(myCallable); //使用FutureTask来包装MyCallable对象
for (int i = 0; i < 10; i++)
System.out.println(Thread.currentThread().getName() + " " + i);
if (i == 3)
Thread thread = new Thread(ftask); //FutureTask对象作为Thread对象的target创建新的线程
thread.start(); //线程进入到就绪状态
System.out.println("主线程for循环执行完毕...");
try
int sum = ftask.get(); //取得新创建的新线程中的call()方法返回的结果
System.out.println("sum = " + sum);
catch (InterruptedException e)
e.printStackTrace();
catch (ExecutionException e)
e.printStackTrace();
//仅使用方法4实现
class RunnableThread implements Runnable
@Override
public void run()
System.out.println("通过线程池方式创建的线程:" + Thread.currentThread().getName() + " ");
public class ThreadTest
private static int POOL_NUM = 20; //线程池数量
public static void main(String[] args) throws InterruptedException
//线程池
ExecutorService executorService = Executors.newFixedThreadPool(5);
for(int i = 0; i<POOL_NUM; i++)
RunnableThread thread = new RunnableThread();
//Thread.sleep(5000);
executorService.execute(thread);
//或者
executorService.submit(thread);
//execute和submit的区别:
//接收的参数不一样,submit可以是Callable、Runnable,execute只能是Runnable
//submit有返回值,而execute没有
//submit方便Exception处理
//关闭线程池
executorService.shutdown();
/*
首先创建线程池,然后利用FutureTask对象的get()来获取子线程执行结束的返回值用于后续程序的处理。
*/
// 创建一个临时的局部线程池(固定大小)
ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
// 保存结果
List<Future<List<String>>> futures = new ArrayList<Future<List<String>>>(partions.size());
// 分配任务
for (int i = 0; i < partions.size(); i++)
// 小任务
callTask = new CallableTest(partions.get(i));
//同步执行多个小任务
futures.add(executorService.submit(callTask));
// 关闭线程池
executorService.shutdown();
//获取结果
List<String> result = new ArrayList<String>();
result.addAll(future.get());
参考资料:
https://blog.csdn.net/hekf2010/article/details/86546262 多线程并行执行,然后汇总结果
https://www.cnblogs.com/huangdabing/p/9251598.html Java多线程处理List数据
https://my.oschina.net/java520me/blog/812646 java List集合中按一定数量进行分组输出
https://blog.csdn.net/kunfd/article/details/113922781?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-1.pc_relevant_without_ctrlist&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-1.pc_relevant_without_ctrlist&utm_relevant_index=1 多线程处理List并将结果合并
系统运维系列之异常抛出后代码执行问题(java应用)
1问题描述thrownewExcpetion()之后,程序并没有向下继续运行,抛出异常后直接跳出,后面的功能不再执行。//抛出异常:Exceptioninthread"main"java.lang.NumberFormatException//不会执行后面的输出语句publicstaticvoidmain(String[]args) S... 查看详情
系统运维系列之mysql部分学习整理4
1存储引擎查看数据库表创建命令:SHOWCREATETABLEtab1;支持的存储引擎:MylSAM:快速存储;InnoDB:带有事务回滚机制;MemorycsvArchive修改存储引擎的方式:通过修改MySQL配置文件实现default-storage-engine=engine... 查看详情
系统运维系列之list实现深拷贝(java应用)
浅拷贝调用方法:遍历循环复制:List<String>destList=newArrayList<String>(srcList.size());for(Stringp:srcList)destList.add(p);使用list.addAll()方法:List<String>destList=newAr 查看详情
系统运维系列之堆栈理解(java应用)(代码片段)
1概述java虚拟机内存分为:堆(heap)、栈(stack)、方法区(methodarea)等,整体来说:堆:new出来的数组或者对象;栈:存储局部变量;方法区:代码区;寄存器 查看详情
系统运维系列之socket和serversocket的简单介绍(java应用)
Socket类代表一个客户端套接字,即任何时候连接到一个远程服务器应用时构建所需的socket。现在,要实现一个服务器应用,需要不同的做法。服务器需随时待命,因为不知道客户端什么时候会发来请求,此时... 查看详情
系统运维系列之clickhouse数据类型整理
Clickhouse支持的数据类型在system.data_type_families表中检查数据类型名称以及是否区分大小写,这个表中存储了ClickHouse支持的所有数据类型。select*fromsystem.data_type_familieslimit10;Int说明ClickHouse中整形分为Int8、Int16、Int32、Int64来表示... 查看详情
系统运维系列之mysql部分学习整理3
1存储过程语法结构:举例:无参CREATEPROCEDUREsql()SELECTVERSION();调用:CALLsql();有参IN:DELIMITER//(更改执行符号的命令)参数与语句中的字段不要重复,不要重复!如果p_id改成id,则会全部删除... 查看详情
系统运维系列之mysql部分学习整理2
1字符函数使用举例:CONCAT_WS相比于CONCAT可以简化语句SELECTCONCAT(id,’-’,age)ASpathFROMuser;SELECTCONCAT_WS(’-’,id,age)ASpathFROMuser;SELECTFORMAT(id,3)ASnumFROMuser;SELECTLEFT(‘abcdef’,2);—>ab举例:SELECT 查看详情
系统运维系列之mysql部分学习整理1
1前言本部分对于MySQL数据库工作机制及其语法做一个整理,用于之后重点内容的查询和交流。2包含内容数据库工作机制、语法基础、重要内容整理、语句优化、效率提升等。3MySQL的字段约束3.1其中AUTO_INCREMENT必须和PRIMARYKEY一... 查看详情
系统运维系列之greenplumvacuum清理删除数据命令(代码片段)
...m完成清理工作后,那些空间并没有真正被释放给操作系统,只能被vacuum清理过的表和索引所利用 查看详情
自动化运维系列之ansible的简介与安装持续更新···(代码片段)
自动化运维系列之Ansible的简介与安装自动化运维工具简介由于互联网的快速发展导致产品更新换代的速度逐渐加快,这就导致运维人员的日常工作会大大增加,如果还是按照传统方式进行维护工作会使工作效率低下。此时,就... 查看详情
系统运维系列之greenplum常用的toolkit和catalog监控语句
1表膨胀相关查询--该视图显示了那些膨胀的(在磁盘上实际的页数超过了根据表统计信息得到预期的页数)正规的堆存储的表。select*fromgp_toolkit.gp_bloat_diag;--所有对象的膨胀明细select*fromgp_toolkit.gp_bloat_expected_pages;2表倾斜... 查看详情
系统运维系列之linux系统下常用查找命令整理(代码片段)
1前言网上关于linux命令大多写的很细很全,但是真正使用起来需要根据自己的场景进行拼接,本博客建立在实际场景下,在实际问题中使用linux查找命令。2grep命令使用场景:查找日志中的关键词,并且限定时... 查看详情
系统运维系列之mysql联合索引的使用分析(代码片段)
1前言日常优化中可能会遇到相同的数据在本地执行很快但是在服务器上执行很慢的问题,或者无论是在本地还是在服务器上都执行的很慢,可以分为两个方面排查2第一部分本地执行速度>服务器执行速度一般这种情况... 查看详情
系统运维系列之mysql部分学习整理5(代码片段)
1应用场景在mysql数据库中查找数据,要求是数据为日期不连续数据,输入一个日期查询日期所在周指定周几的数据和上几周对应时间段数据(一个月内)。关于此问题网上资料未曾有明确的解决方案,本篇博... 查看详情
自动化运维系列之ansible命令应用基础(模块的应用)持续更新中···(代码片段)
自动化运维系列之Ansible命令应用基础(模块的应用)模块简介Ansible可以使用命令行方式进行自动化管理,基本语法如下:ansible<host-pattern>[-mmodule_name][-aargs]<host-pattern>对哪些主机生效[-mmodule_name]需要使用的模块[-aargs]模块... 查看详情
系统运维系列之ip地址和子网划分介绍(代码片段)
1简介接上一篇博客:关于A类,B类,C类IP地址的网段和主机数的计算方法2详细内容(1)子网掩码IP地址是以网络号和主机号来标示网络上的主机的,我们把网络号相同的主机称之为本地网络,网络号不相同的主... 查看详情
系统运维系列之java中需要转义的特殊字符(代码片段)
在Java中,不管是String.split(),还是正则表达式,有一些特殊字符需要转义,这些字符是:([/^-$¦])?*+.转义方法为字符前面加上"\\",这样在split、replaceAll时则不会报错;//replace和replaceAll区别... 查看详情