线程池 - 02

根据阿里开发手册对线程池进行优化,

【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,
这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

即添加一个线程工厂,将线程池放入线程工厂,主要是易于发现线程出错原因和定位,规避资源耗尽

说明:Executors 各个方法的弊端:
1)newFixedThreadPool 和 newSingleThreadExecutor:
主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至 OOM。
2)newCachedThreadPool 和 newScheduledThreadPool:
主要问题是线程数最大数是 Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至 OOM。

ThreadPoolExecutor :

  public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) 
RejectedExecutionHandler handler 拒绝策略:

ThreadPoolExecutor.AbortPolicy: 丢弃任务并抛出RejectedExecutionException异常。 (默认)
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

改进成:

            ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("MQTT接收通道-%s").build();

            ExecutorService pool = new ThreadPoolExecutor(5,200,20,
                    TimeUnit.SECONDS,new SynchronousQueue<>(),namedThreadFactory,new ThreadPoolExecutor.AbortPolicy());



            // 设置回调函数
            client.setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable cause) {
                    System.out.println("connectionLost");
                }
                @Override
                public void messageArrived(String topic, MqttMessage message) throws Exception {
                    System.out.println(message);
                    //新建线程 放入任务
                    MyThread task = new MyThread(msgHandler,topic,message);
                    //把线程任务丢给线程池处理
                    pool.execute(task);
                }
                @Override
                public void deliveryComplete(IMqttDeliveryToken token) {
                    System.out.println("deliveryComplete---------"+ token.isComplete());
                }
            });

猜你喜欢

转载自www.cnblogs.com/zhuangyao/p/12651798.html