Java通过Executors提供四种线程池,分别为:
1,newCachedThreadPoo
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
2,newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
3,newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。
4,newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
简单Demo
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;
public class ThreadDemo {
public static void main(String[] args) {
long st = System.currentTimeMillis();
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
// 无返回值
executorService.execute(new ThreadHandle());
}
long et = System.currentTimeMillis();
System.out.println("-----执行时间----- " + (et - st));
st = System.currentTimeMillis();
// 有返回值
ArrayList<Future<Long>> arrayList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Future<Long> future = executorService.submit(new ThreadCallable<Long>() {
@Override
public Long handle() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
return System.currentTimeMillis();
}
});
arrayList.add(future);
}
for (Future<Long> future : arrayList) {
try {
System.out.println("data: "+future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
et = System.currentTimeMillis();
System.out.println("-----执行时间2----- " + (et - st));
}
}
class ThreadHandle implements Runnable {
@Override
public void run() {
try {
Thread.sleep(200);
System.out.println("time: "+System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
abstract class ThreadCallable<V> implements Callable<V> {
@Override
public V call() throws Exception {
return handle();
}
public abstract V handle();
}
测试结果:多个线程处理数据的时间
阿里的 Java开发手册,上面有线程池的一个建议:
【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,
这样的处理更加明确线程池的运行规则,规避资源耗尽的风险。
/**
* public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,
* TimeUnit unit,BlockingQueue<Runnable> workQueue)
* corePoolSize用于指定核心线程数量
* maximumPoolSize指定最大线程数
* keepAliveTime和TimeUnit指定线程空闲后的最大存活时间
* workQueue则是线程池的缓冲队列,还未执行的线程会在队列中等待
* 监控队列长度,确保队列有界
* 不当的线程池大小会使得处理速度变慢,稳定性下降,并且导致内存泄露。如果配置的线程过少,则队列会持续变大,消耗过多内存。
* 而过多的线程又会 由于频繁的上下文切换导致整个系统的速度变缓——殊途而同归。队列的长度至关重要,它必须得是有界的,这样如果线程池不堪重负了它可以暂时拒绝掉新的请求。
* ExecutorService 默认的实现是一个无界的 LinkedBlockingQueue。
*/
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,corePoolSize,10l,TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(1000));
参考:
https://www.cnblogs.com/CarpenterLee/p/9558026.html
https://blog.csdn.net/achuo/article/details/80623893
https://blog.csdn.net/weixin_43148691/article/details/84678954