最近在看线程池,简单总结一下,希望对大家稍微有点帮助。
java线程池创建可以使用Executors类去创建,它是对ThreadPoolExecutor进行封装。
其中Executors.newFixedThreadPool是创建一个线程数量和最大线程数相等,并且队列是无限大
LinkedBlockingQueue的线程池,当我们使用时,当任务数大于线程数时,任务会一直向队列里面增加,可能会造成内存溢出。
使用代码如下:
package test.thread.pool; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class FixThreadPool { static class Task implements Runnable { private int i; private String name; public Task(int i, String name) { this.i = i; this.name = name; } @Override public void run() { System.out.println(name + " " + Thread.currentThread().getName() + " print " + i); } } public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(10); for (int i = 0; i < 10000; i++){ Task task = new FixThreadPool.Task(i, "fixedThreadPool"); executor.execute(task); } executor.shutdown(); } }
可以看到,fixedThreadPool线程池,当线程数量不够时候,不会增加线程,而是全部加到队列里面去,容易造成OOM。
Executors.newSingleThreadPool是创建一个线程数量和最大线程数相等,并且队列是无限大的线程池,当我们使用时,任务会一直向队列里面增加,可能会造成内存溢出。但是它和fixedThreadPool的区别是线程核心线程数量和线程总数量都为1,并且被 FinalizableDelegatedExecutorService修饰。
使用单个线程时,线程的创建方式类似,只不过把newFixedThreadPool改成newSingleThreadPool,但是此线程池中只有一个线程,但是由于也是队列是无限大小,所以任务都会加到队列中,所以也可能造成内存溢出。
缓存线程池:
缓存线程池是创建一个最大线程数是Integer.MAX_VALUE的线程,队列大小不限制的
SynchronousQueue线程池,任务数量大于线程数量时,会创建线程,最大Integer.MAX_VALUE。
打印信息科看到,由于会一直创建线程,所以也会造成OOM。 scheduledThreadPool是创建一个最大线程数是Integer.MAX_VALUE的线程,队列大小不限制的线程池。
这种线程池和fixThreadPool创建线程池的方式差不多,所以也很容易造成OOM。
综上,最好自己手动去创建线程池,自己去管理线程数量和队列大小,这样可以避免造成OOM的问题。