java线程池之Executors和ThreadPoolExecutors区别

Excutors和ThreadPoolExcutor创建线程池的区别

Executors 各个方法的弊端:

  • newFixedThreadPool 和 newSingleThreadExecutor:
    主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至 OOM。
  • newCachedThreadPool 和 newScheduledThreadPool:
    主要问题是线程数最大数是 Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至 OOM。

什么是OOM?
OOM,全称“Out Of Memory”,翻译成中文就是“内存用完了”,来源于java.lang.OutOfMemoryError。看下关于的官方说明: Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector. 意思就是说,当JVM因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时,就会抛出这个error(注:非exception,因为这个问题已经严重到不足以被应用处理)

ThreaPoolExecutor

创建线程池方式只有一种,就是走它的构造函数,参数自己指定

两种提交任务的方法(execute 和 submit)

ExecutorService 提供了两种提交任务的方法:

  • execute():提交不需要返回值的任务
  • submit():提交需要返回值的任务

execute

void execute(Runnable command);

execute() 的参数是一个 Runnable,也没有返回值。因此提交后无法判断该任务是否被线程池执行成功。

ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(new Runnable() {
    
    
    @Override
    public void run() {
    
    
        //do something
    }
});

submit

<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);

submit() 有三种重载,参数可以是 Callable 也可以是 Runnable。

同时它会返回一个 Funture 对象,通过它我们可以判断任务是否执行成功。

获得执行结果调用 Future.get() 方法,这个方法会阻塞当前线程直到任务完成。

提交一个 Callable 任务时,需要使用 FutureTask 包一层:

FutureTask futureTask = new FutureTask(new Callable<String>() {
    
       
	 //创建 Callable 任务
    @Override
    public String call() throws Exception {
    
    
        String result = "";
        //do something
        return result;
    }
});

//提交到线程池
Future<?> submit = executor.submit(futureTask);
try {
    
    
	 //获取结果
	 Object result = submit.get();   
} catch (InterruptedException e) {
    
    
    e.printStackTrace();
} catch (ExecutionException e) {
    
    
    e.printStackTrace();
}

猜你喜欢

转载自blog.csdn.net/qq_22764659/article/details/111290718
今日推荐