51、多线程创建的三种方式之实现Callable接口
实现Callable接口创建线程
Callable接口是在jdk5版本中加入的,这个接口在java.util.concurrent包下面,与其他两种方式不同的地方在于使用Callable接口创建的线程会获得一个返回值并且可以声明异常。
使用Callable创建线程步骤:
1.自定义一个类实现java.util.concurrent包下的Callable接口
2.重写call方法
3.将要在线程中执行的代码编写在call方法中
4.创建ExecutorService线程池
5.将自定义类的对象放入线程池里面
6.获取线程的返回结果
7.关闭线程池,不再接收新的线程,未执行完的线程不会被关闭
package com.sutaoyu.Thread; import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; class MyCallable implements Callable<Integer>{
//睡眠时间
private long second; //计算阶乘
private int count; public MyCallable(int count, long second) {
this.count = count;
this.second = second;
} //重写call方法
@Override
public Integer call() throws Exception {
// 3.将要执行的代码写在call方法中
// 计算阶乘
//让当前线程睡眠,单位是毫秒 Thread.sleep(second);
int sum = 1;
if(count == 0) {
sum = 0;
}else {
for(int i = 1;i <= count;i++) {
sum *= 1;
}
} //打印线程名称
System.out.println(Thread.currentThread().getName() + "--------sum=" + sum); return sum;
}
public int getCount() {
return count;
} public void setCount(int count) {
this.count = count;
}
} public class test_3 { public static void main(String[] args) throws InterruptedException, ExecutionException {
//4.创建ExecutorService线程池
ExecutorService exec = Executors.newCachedThreadPool(); //5.创建存储Future对象的集合,用来存放ExecutorService的执行结果
ArrayList<Future<Integer>> results = new ArrayList<Future<Integer>>(); //6.开启2个线程,将返回的Future对象放入集合中
for(int i = 0;i < 2;i++) {
if(i == 0) {
//计算5的阶乘,睡眠10秒
results.add(exec.submit(new MyCallable(5, 10000)));
}else {
//计算3的阶乘,睡眠i秒
results.add(exec.submit(new MyCallable(3, i)));
}
}
for (Future<Integer> fs : results) {
//7.判断线程是否执行结束,如果执行结束就将结果打印
if (fs.isDone()) {
System.out.println("计算结果:" + fs.get());
} else {
System.out.println(fs.toString() + "该线程还没有计算完毕,请耐心等待");
}
} //8.关闭线程池,不再接收新的线程,未执行完的线程不会被关闭
exec.shutdown();
System.out.println("main方法执行结束");
}
}
线程池
线程池是初始化一个多线程应用程序过程中创建一个线程集合,然后在需要执行新的任务时直接去这个线程集合中获取,而不是创建一个线程。任务执行结束后,线程回到池子中等待下一次的分配。
线程池的作用
解决创建单个线程耗费时间和资源的问题。
创建线程池
上面代码中演示了两种方式创建线程池
- Executors.newFixedThreadPool(int nThreads);
通过传入的int类型参数来指定创建线程池中的线程数,如果任务6666666666666数量大于线程数量,则任务会进行等待。 - Executors.newCachedThreadPool();
会根据需要创建新线程的线程池,如果线程池中的线程数量小于任务数时,会创建新的线程,线程池中的线程最大数量是Integer.MAX_VALUE,int类型的最大值。如果线程的处理速度小于任务的提交速度时,会不断创建新的线程来执行任务,这样有可能会因为创建过多线程而耗尽CPU 和内存资源。
51、多线程创建的三种方式之实现Callable接口的更多相关文章
- 50、多线程创建的三种方式之实现Runnable接口
实现Runnable接口创建线程 使用Runnable创建线程步骤: package com.sutaoyu.Thread; //1.自定义一个类实现java.lang包下的Runnable接口 cl ...
- 49、多线程创建的三种方式之继承Thread类
继承Thread类创建线程 在java里面,开发者可以创建线程,这样在程序执行过程中,如果CPU空闲了,就会执行线程中的内容. 使用Thread创建线程的步骤: 1.自定义一个类,继承java.lan ...
- 如何实现有返回值的多线程 JAVA多线程实现的三种方式
可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须Runnable接口.执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable ...
- 于Unity3D动态创建对象和创建Prefab三种方式的原型对象
于Unity3D动态创建对象和创建Prefab三种方式的原型对象 u3d在动态创建的对象,需要使用prefab 和创建时 MonoBehaviour.Instantiate( GameObject o ...
- 黑马vue---56-58、vue组件创建的三种方式
黑马vue---56-58.vue组件创建的三种方式 一.总结 一句话总结: 不论是哪种方式创建出来的组件,组件的 template 属性指向的模板内容,必须有且只能有唯一的一个根元素 1.使用 Vu ...
- 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】
一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...
- Java中 实现多线程成的三种方式(继承,实现,匿名内部类)
---------------------------------------------------------------------------------------------------- ...
- JAVA多线程实现的三种方式
JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式线程执行完后都没 ...
- SpringBoot工程创建的三种方式
一. 通过IDEA的spring Initializer创建 1. 打开创建项目面板 File->New->Project->Spring Initializr 2. 填写Maven ...
随机推荐
- php单例模式 (转
假设我们需要写一个类用来操作数据库,并同时满足以下要求: ①SqlHelper类只能有一个实例(不能多)②SqlHelper类必须能够自行创建这个实例③必须自行向整个系统提供这个实例,换句话说:多个对 ...
- windows多线程(七) 事件event
前面说的互斥量Mutex与关键段CriticalSection都不能实现线程的同步,只能实现互斥,接下来我们用时间event就可以实现线程的同步了,事件也是一个内核对象. 一.相关函数说明 (一) 创 ...
- Nginx负载均衡配置与负载策略
原理 负载均衡的目的是为了解决单个节点压力过大,造成Web服务响应过慢,严重的情况下导致服务瘫痪,无法正常提供服务. 应用场景 春节期间在12306网站上买过火车票的朋友应该深有体会,有时查询一张火车 ...
- 微信小程序 功能函数 把数字1,2,3,4换成春,夏,秋,冬
let season =‘1,2,3’; // console.log(season.length) if (season){ if (season.length==1){ seasonChe1=se ...
- PHP中测试in_array、isset、array_key_exists性能
测试in_array.isset.array_key_exists性能.自己写的简易测试代码: ini_set('display_errors',true); error_reporting(E_AL ...
- C++模式学习------单例模式
单例(Singleton)模式,是一种常用的软件设计模式.在应用这个模式时,单例对象的类必须保证只有一个实例存在.许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为.例如一些类 ...
- BZOJ3289 Mato的文件管理(莫队+树状数组)
这个做法非常显然. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib& ...
- 查看临时表空间占用最多的用户与SQL
select sess.username, sql.sql_text, sort1.blocks from v$session sess, v$sqlarea sql, v$sort_usage ...
- 【刷题】BZOJ 4443 [Scoi2015]小凸玩矩阵
Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的N个数中第K大的数字的最 ...
- BZOJ 3210: 花神的浇花集会
3210: 花神的浇花集会 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 577 Solved: 299[Submit][Status][Discus ...