提问
线程的应用场景都有什么?
如果并发数量非常多,但是每个线程执行的时间都特别短,该如何设计?
线程池
A thread pool is a collection of pre-initialized threads.A thread pool reuses previously created threads to execute current tasks and offers a solution to the problem of thread cycle overhead and resource thrashing.
参考:
Thread Pools in Java
Introduction to Thread Pools in Java
什么时候使用线程池?
- 单个任务处理时间比较短
- 需要处理的任务数量很大
使用线程池的好处
- 降低资源消耗
通过重复利用已创建的线程降低线程创建和销毁造成的消耗 - 提高响应速度
当任务到达时,任务可以不需要的等到线程创建就能立即执行 - 提高线程的可管理性
线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
示例
public class WorkerThread implements Runnable {
private String command;
public WorkerThread(String s) {
this.command = s;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " Start. Command = " + command);
processCommand();
System.out.println(Thread.currentThread().getName() + " End.");
}
private void processCommand() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return this.command;
}
}
执行
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
Runnable worker = new WorkerThread("" + i);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
}
System.out.println("Finished all threads");
查看结果,这是一个最简单的线程池的执行方式。而且IDE有警告提示,这并不会有执行问题。
拓展
另外输出一个监听线程,代码如下:
public class MyMonitorThread implements Runnable {
private ThreadPoolExecutor executor;
private int seconds;
private boolean run = true;
public MyMonitorThread(ThreadPoolExecutor executor, int delay) {
this.executor = executor;
this.seconds = delay;
}
public void shutdown() {
this.run = false;
}
@Override
public void run() {
while (run) {
System.out.println(
String.format("[monitor] [%d/%d] Active: %d, Completed: %d, Task: %d, isShutdown: %s, isTerminated: %s",
this.executor.getPoolSize(),
this.executor.getCorePoolSize(),
this.executor.getActiveCount(),
this.executor.getCompletedTaskCount(),
this.executor.getTaskCount(),
this.executor.isShutdown(),
this.executor.isTerminated()));
try {
Thread.sleep(seconds * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
执行方式:
public class WorkerPool {
public static void main(String args[]) throws InterruptedException {
RejectedExecutionHandlerImpl rejectionHandler = new RejectedExecutionHandlerImpl();
/** 用来创建新的线程 **/
ThreadFactory threadFactory = Executors.defaultThreadFactory();
/** 创建线程池 **/
ThreadPoolExecutor executorPool = new ThreadPoolExecutor(2, 4, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(2), threadFactory, rejectionHandler);
MyMonitorThread monitor = new MyMonitorThread(executorPool, 3);
Thread monitorThread = new Thread(monitor);
monitorThread.start();
for (int i = 0; i < 10; i++) {
executorPool.execute(new WorkerThread("cmd" + i));
}
Thread.sleep(30000);
executorPool.shutdown();
Thread.sleep(5000);
monitor.shutdown();
}
}
参考
ThreadPoolExecutor – Java Thread Pool Example
Introduction to Thread Pools in Java
Thread Pools in Java
深入理解 Java 线程池:ThreadPoolExecutor
网友评论