正确创建一个线程池的方法ThreadPoolExecutor

package 修改文件内容;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class xianchengchi {

    public static void main(String[] args) {
        //创建线程严禁使用显示的定义创建线程 如:nebw Thread(),new Runnale(),和使用Executors.newFixedThreadPool newSingleThreadExecutor
        //newCachedThreadPool  newScheduledThreadPool 的方法因为 他们底层都会调用到new ThreadPoolExecutor()方法,而这个方法里面的最大线程数量参数有的是nteger.MAX_VALUE
        //或者他们底层的阻塞队列调用的是阻塞队列无参的构造函数,而他们的无参构造函数里面创建出来的阻塞队列的大小是Integer.MAX_VALUE的
        //最终造成可能会堆积大量的请求,从而导致 OOM。或者可能会创建大量的线程,从而导致 OOM。
        //特别注意 new LinkedBlockingQueue(2)一定要用有参数的构造函数指定阻塞队列的最大大小
        //此例子 创建2个核心,3个非核心线程,可以最多处理5个任务的并发量,任务大于5个时最多的可以进入阻塞队列的任务数量为2,如果来的任务数量超过了7个就会根据拒绝策略处理
        ExecutorService executorService =new ThreadPoolExecutor(2, 5, 0, TimeUnit.SECONDS,  new LinkedBlockingQueue(2), Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardPolicy());
        for (int i = 0; i <5; i++) {
            executorService.execute(new Runnable(){
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    System.out.println(Thread.currentThread().getName());
                }
                
            });
        }
        executorService.shutdown();
        // TODO Auto-generated method stub
//总结:
        /*4. 【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样
        的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
        说明:Executors 返回的线程池对象的弊端如下:
        1)FixedThreadPool 和 SingleThreadPool:
        允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM。
        2)CachedThreadPool 和 ScheduledThreadPool:
        允许的创建线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,从而导致 OOM。*/
        
    }

}
 

你可能感兴趣的:(线程)