在JDK1.5版,Java标准包中就包含了对线程池的支持,提供了包java.lang.concurrent
.
1. ThreadPool
线程池是一个线程管理的集合,能够有效执行任务。当大量任务使用线程池执行时,由于线程循环的执行,整个性能得到提高,也减少了每个任务调用上的花费。实现线程池,你能够运用ExecutorService的实现类,比如ThreadPoolExecutor
或是ScheduledThreadPoolExecutor。另外,在类Executors
中提供了如下更方便的工厂方法:
-
Executors.newSingleThreadExecutor()
: 创建一个单一后台线程实例.
-
Executors.newFixedThreadPool(int numThreads)
: 创建一个可以修复线程池大小实例.
-
Executors.newCachedThreadPool()
:运用自动化线程回收利用来创建一个非绑定线程池实例。
使用线程池的步骤如下:
- 编写出实现了Runnable接口的工人线程类,run()方法指定了运行线程的行为。
- 使用由Executor类提供的工厂方法创建一个线程池(
ExecutorService
),这个线程池可以是Executors.newSingleThreadExecutor(),或者Executors.newFixedThreadPool(int
numThreads),也可以是Executors.newCachedThreadPool()创建的。
- 创建你的工人线程实例,使用execute(Runnable)方法去添加一个Runnable任务到线程池中。如何在池中有一个有效的线程,这个任务将会被调度并执行。
2. 理解相关API
一个Executor对象能够执行Runnable提交的任务。Executor接口类(1.6version)中的方法:
void execute(Runnable command);
它在不久的某个时间里执行一个给予任务。
接口ExecutorService定义了一些有用的方法,重要的两个如下:
public void shutdown();
// Initiates an orderly shutdown of the thread pool.
// The previously executed/submitted tasks are allowed to complete,
// but no new tasks will be scheduled.
public <T> Future<T> submit(Callable<T> task);
// Submit or schedule the callable task for execution, which returns a Future object.
Executors类中定义一些有用的方法:
static ExecutorService newSingleThreadExecutor()
static ExecutorService newFixedThreadPool(int nThreads)
static ExecutorService newCachedThreadPool()
static ScheduledExecutorService newSingleThreadScheduledExecutor()
static ScheduledExecutorService newScheduledThreadPool(int size)
一个简单的例子来说明一下如何调用使用线程池。
public class WorkerThread implements Runnable {
private int workerNumber;
WorkerThread(int workerNumber) {
this.workerNumber = workerNumber;
}
public void run() {
// The thread simply prints 1 to 5
for (int i = 1; i <= 5; i++) {
System.out.printf("Worker %d: %d\n", workerNumber, i);
try {
// sleep for 0 to 0.5 second
Thread.sleep((int)(Math.random() * 500));
} catch (InterruptedException e) {}
}
}
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolTest {
public static void main(String[] args) {
int numWorkers = Integer.parseInt(args[0]);
int threadPoolSize = Integer.parseInt(args[1]);
ExecutorService pool =
Executors.newFixedThreadPool(threadPoolSize);
WorkerThread[] workers = new WorkerThread[numWorkers];
for (int i = 0; i < numWorkers; i++) {
workers[i] = new WorkerThread(i+1);
pool.execute(workers[i]);
}
pool.shutdown();
}
}
结果如下:
Worker 1: 1
Worker 2: 1
Worker 2: 2
Worker 2: 3
Worker 2: 4
Worker 1: 2
Worker 1: 3
Worker 2: 5
Worker 1: 4
Worker 1: 5
Worker 3: 1
Worker 3: 2
Worker 4: 1
Worker 3: 3
Worker 3: 4
Worker 4: 2
Worker 3: 5
Worker 4: 3
Worker 5: 1
Worker 4: 4
Worker 5: 2
Worker 5: 3
Worker 4: 5
Worker 5: 4
Worker 5: 5
接口Callable和Runnable。
Callable与Runnable很相似。然而,
Callable提供了一种能够固定在线程上的返回结果或是出现的异常。
public V call()
// Call() returns a result of type <V>, or throws an exception if unable to do so.
在线程池中,使用submit(Callable r)可以返回一个Future<V>(在ExecutorService接口
类中声明
)对象。当需要有返回结果时,可以检索get()方法来获得。如果不出现异常,会返回准备的结果。
Future<V>的方法如下:
V get() // wait if necessary, retrieve result
V get(long timeout, TimeUnit unit)
boolean cancel(boolean mayInterruptIfRunning)
boolean isCancelled()
boolean isDone() // return true if this task completed
同样的例子,换一种写法:
public class CallableWorkerThread implements Callable<String> {
private int workerNumber;
CallableWorkerThread(int workerNumber) {
this.workerNumber = workerNumber;
}
public String call() { // use call() instead of run()
for (int i = 1; i <= 5; i++) { // just print 1 to 5
System.out.printf("Worker %d: %d\n", workerNumber, i);
try {
Thread.sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {}
}
return "worker " + workerNumber;
}
}
package org.concurrency.simple;
/**
* @author: John Liu
*/
import java.util.concurrent.*;
public class CallableThreadPoolTest {
public static void main(String[] args) {
int numWorkers = 5;
ExecutorService pool = Executors.newCachedThreadPool();
CallableWorkerThread workers[] = new CallableWorkerThread[numWorkers];
Future[] futures = new Future[numWorkers];
for (int i = 0; i < numWorkers; i++) {
workers[i] = new CallableWorkerThread(i + 1);
futures[i] = pool.submit(workers[i]);
}
for (int i = 0; i < numWorkers; i++) {
try {
System.out.println(futures[i].get() + " ended");
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (ExecutionException ex) {
ex.printStackTrace();
}
}
}
}
结果:
Worker 2: 1
Worker 4: 1
Worker 5: 1
Worker 1: 1
Worker 3: 1
Worker 4: 2
Worker 4: 3
Worker 2: 2
Worker 4: 4
Worker 5: 2
Worker 1: 2
Worker 3: 2
Worker 4: 5
Worker 5: 3
Worker 2: 3
Worker 5: 4
Worker 3: 3
Worker 1: 3
Worker 2: 4
Worker 1: 4
Worker 3: 4
Worker 5: 5
Worker 2: 5
Worker 1: 5
Worker 3: 5
worker 1 ended
worker 2 ended
worker 3 ended
worker 4 ended
worker 5 ended
分享到:
相关推荐
hadoop自带的Container-executor在配置yarn-kerberos时存在问题,以及在配置cgroup时需要把container-executor.cfg的上级目录拥有者均改为root,带来不便。 所以需要重新编译Container-executor,这边提供重新编译好...
技术方案基于ExecutorService、Callable、Future等高级Java并发API。 技术栈 JDK 8 Apache Maven v.3.2 构建说明 从应用程序根目录调用以下 maven 命令: mvn clean package 检查构建日志,确保构建成功: ...
hadoop自带的Container-executor在配置yarn-kerberos时存在问题,这边给出编译后的Container-executor,默认加载配置文件路径/etc/container-executor.cfg,大家不用再重新编译了
IThreadPool executor = new ThreadPool (config . properties); executor . start(); // ... // Execute something. // executor.execute(runnable); // ... // Send shutdown signal. // Will shutdown only ...
2023-06-09 22:23:25.593906: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'cublas64_11.dll'; dlerror: cublas64_11.dll not found 2023-06-09 22:23:25....
用户应用new SparkContext后,集群就会为在Worker上分配executor,但是增加executor的时候需要考虑好内存消耗,因为一台机器的内存分配给越多的executor,每个executor的内存就越小,以致出现过多的数据spill over...
11.3.1 Thread Pool Executor / 407 11.3.2 线程池的分类 / 410 第12章 Bitmap的加载和Cache / 413 12.1 Bitmap的高效加载 / 414 12.2 Android中的缓存策略 / 417 12.2.1 Lru Cache / 418 12.2.2 Disk ...
高效率 快捷操作
mybatis中的sqlsession--executor实现 mybatis中的sqlsession--executor实现
基于Android开发的Executor线程池示例
包括被执行任务需要实现的接口:Runnable接口或者Callable接口。 任务的执行 。包括任务执行机制的核心接口Executor,以及继承自Executor的ExecutorService接口。Executor框架有两个关键类实现了ExecutorService...
该文档详细记录了Executor框架结构、使用示意图、ThreadPoolExecutor使用示例、线程池原理分析、几种常见线程池(FixedThreadPool、SingleThreadExecutor、CachedThreadPool)的详解以及线程池大小确定等内容
FANUC C Language Executor
npm install eager-async-pool或yarn add eager-async-pool const { asyncPool } = require ( 'eager-async-pool' ) // exceptionally useful executor const executor = ( n ) => 'Number is: ' + n // absolutely...
/ 392 11.2.1 Async Task / 392 11.2.2 Async Task的工作原理 / 395 11.2.3 Handler Thread / 402 11.2.4 Intent Service / 403 11.3 Android中的线程池 / 406 11.3.1 Thread Pool Executor / 407 11.3.2 ...
Executor: 一个接口,其定义了一个接收Runnable对象的方法...new Thread(new RunnableTask())).start(),但在Executor中,可以使用Executor而不用显示地创建线程:executor.execute(new RunnableTask()); // 异步执行
非常好的Java并发框架Executor图例,结构清晰,继承关系清楚。
xxl-job-executor的gin中间件背景xxl-job-executor-go是xxl-job的golang执行器,可以独立运行,有时候我们要与项目或者框架(如:gin框架)集成起来合并为一个服务,本项目因此而生。执行器项目地址与gin集成示例...
Nagios远程插件执行器/ PERL(NRPEP)是客户端/服务器接口的PERL实现,旨在为Nagios监视系统提供一种远程执行插件的安全方法。
executor 查找工具,方便查找应用软件,可以自定义文件快捷键。