Java多线程之Callable接口与Runnable的实现以及选择
通过实现Runnable接口的实现
package Thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class RunnableThreadDemo {
private static int POOL_NUM = 30; // 线程池数量
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < POOL_NUM; i++) {
RunnableThread thread = new RunnableThread();
//线程停顿
Thread.sleep(1000);
executorService.execute(thread);
}
// 关闭线程池
executorService.shutdown();
}
}
class RunnableThread implements Runnable {
@Override
public void run() {
System.out.println("通过线程池方式创建的线程Runnable方式:" + Thread.currentThread().getName() + " ");
}
}
通过实现Runnable接口的实现
package Thread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class CallableThreadDemo {
private static int POOL_NUM = 30; // 线程池数量
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < POOL_NUM; i++) {
Callable<Integer> callableThread = new CallableThread();
FutureTask<Integer> thread = new FutureTask<Integer>(callableThread);
//线程停顿
Thread.sleep(1000);
//执行 Callable 方式,需要 FutureTask 实现类的支持,用于接收运算结果。 FutureTask 是 Future 接口的实现类
executorService.submit(thread);
System.out.println(thread.get());
}
// 关闭线程池
executorService.shutdown();
}
}
class CallableThread implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("通过线程池方式创建的线程Callable方式:" + Thread.currentThread().getName() + " ");
return 10086;
}
}
1.Callable规定的方法是call(),而Runnable规定的方法是run().
2.Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
3.call() 方法可抛出异常,而run() 方法是不能抛出异常的。
4.运行Callable任务可拿到一个Future对象, Future表示异步计算的结果。
5.它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。
6.通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。
7.Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。
ExecutorService、Callable都是属于Executor框架。返回结果的线程是在JDK1.5中引入的新特征,还有Future接口也是属于这个框架,有了这种特征得到返回值就很方便了。
通过分析可以知道,他同样也是实现了Callable接口,实现了Call方法,所以有返回值。这也就是正好符合了前面所说的两种分类
执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了。get方法是阻塞的,即:线程无返回结果,get方法会一直等待。
再介绍Executors类:提供了一系列工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口。
public static ExecutorService newFixedThreadPool(int nThreads)
创建固定数目线程的线程池。
public static ExecutorService newCachedThreadPool()
创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。
public static ExecutorService newSingleThreadExecutor()
创建一个单线程化的Executor。
public static ScheduledExecutorService newScheduledThreadPool(int
corePoolSize)
创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。
ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。
为什么要用线程池:
1.减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
2.可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。
Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是ExecutorService。
题外话,Thread表示一个线程,每个任务都创建一个线程肯定是不妥的,正确的做法应该是初始化一定量的Thread对象,实现Runnable接口创建表示任务的类,并把这些任务对给Thread线程执行。
我们应该是使用Runnable还是Thread?
Java不支持多继承,但允许实现多个接口。所以如果需要继承其他类,实现Runnable接口是好了。
---------------------
作者:性情中人1993
来源:CSDN
原文:https://blog.csdn.net/qq_38765404/article/details/81163959
版权声明:本文为博主原创文章,转载请附上博文链接!
Java多线程之Callable接口与Runnable的实现以及选择的更多相关文章
- Java多线程之Callable接口的实现
Callable 和 Future接口 Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务. Callable和Runn ...
- java多线程之Callable、Future和FutureTask
Java并发编程:Callable.Future和FutureTask 在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一 ...
- Java多线程之Runnable与Thread
Java多线程之Thread与Runnable 一.Thread VS Runnable 在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类和 ...
- Java线程之Callable和Future
本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果. Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结 ...
- JAVA多线程之UncaughtExceptionHandler——处理非正常的线程中止
JAVA多线程之UncaughtExceptionHandler——处理非正常的线程中止 背景 当单线程的程序发生一个未捕获的异常时我们可以采用try....catch进行异常的捕获,但是在多线程环境 ...
- java多线程之wait和notify协作,生产者和消费者
这篇直接贴代码了 package cn.javaBase.study_thread1; class Source { public static int num = 0; //假设这是馒头的数量 } ...
- Java多线程之ConcurrentSkipListMap深入分析(转)
Java多线程之ConcurrentSkipListMap深入分析 一.前言 concurrentHashMap与ConcurrentSkipListMap性能测试 在4线程1.6万数据的条件下, ...
- JAVA多线程之wait/notify
本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法. ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait ...
- JAVA多线程之volatile 与 synchronized 的比较
一,volatile关键字的可见性 要想理解volatile关键字,得先了解下JAVA的内存模型,Java内存模型的抽象示意图如下: 从图中可以看出: ①每个线程都有一个自己的本地内存空间--线程栈空 ...
随机推荐
- React项目
React项目 React项目搭建与部署 一,介绍与需求 1.1,介绍 1.1.1,React简介 React 是一个用于构建用户界面的 JAVASCRIPT 库. React主要用于构建UI,很多人 ...
- Linux下部署tomcat及tomcat war包应用程序
1, 通过winscp将tomcat包(6和7版本都是一样的安装方法)和jdk-6u27-linux-x64.bin安装文件传送到linux 系统/opt里面.(这里没有固定要传送到/opt/hn,可 ...
- RPO漏洞学习
不能直接复制markdown上来真的是痛苦,图片还要手动上传. 算了,不贴了. 这是PDF版https://files.cnblogs.com/files/r00tuser/RPO%E6%BC%8F% ...
- java 使用grpc步骤
1.配置grpc maven依赖 <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-ne ...
- 每日踩坑 2018-09-29 .Net Core 控制器中读取 Request.Body
测试代码: 结果: PostMan: 代码: private string GetRequestBodyUTF8String() { this.Request.EnableBuffering(); ; ...
- JFreeChart 之折线图
JFreeChart 之折线图 一.JFreeChart 简介 JFreeChart是JAVA平台上的一个开放的图表绘制类库.它完全使用JAVA语言编写,是为applications, applets ...
- Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) A. Broken Clock 水题
A. Broken Clock 题目连接: http://codeforces.com/contest/722/problem/A Description You are given a broken ...
- [原创]Jmeter工具学习思维导图
[原创]Jmeter工具学习思维导图
- Bugzilla Error message: couldn't create child process: 720003: index.cgi
two steps is try to fix this issue. 1. Turn off the windowns firewall 2. Register the perl to the sy ...
- stm32的swd接口的烧写协议是否公开的呢?
stm32的swd接口的烧写协议是否公开的呢? 需要用一台好的示波器来抓才能有足够的存储深度,保证你能够过滤掉那个该死的50clock. 按照Arm的手册,每次转换发送方都需要一个TNR---但是我观 ...