java线程池的应用-有界队列线程池

 前言:在java道路上前行中,避免不了使用多线程,在这里做一下笔记。

  1. 我用到是有界队列的线程池。
  2. 如果需要返回值,则需要实现Callable接口,并用Future对象去接收,用.get()方法即可得到返回值
  3. 线程池大小maximumPoolSize我设置为8,一般情况下设置为内核数的两倍(个人经验)
  4. 线程池对拒绝任务的处理策略,需要根据自己的业务进行选择,ThreadPoolExecutor提供了四中

代码:

package com.hzed.interactive.test;

import com.alibaba.druid.util.DaemonThreadFactory;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.Date;
import java.util.concurrent.*;

/**
 * @Author: dayydream
 * @Description: 线程池-有界队列
 * @Date: 14:47 2018/10/17
 * @Modified By:
 */
@Slf4j
public class ThreadDemo {

    //自定义线程名称
    private final static String poolName = "mypool-%d";
    //等待队列
    public ArrayBlockingQueue queue = null;

    //线程执行器
    private ExecutorService excutor;

    public ThreadDemo() {
        /**
         * 线程工厂
         * 二者用其一即可
         */
        DaemonThreadFactory daemonThreadFactory = new DaemonThreadFactory(poolName);
        ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat(poolName).build();

        //等待队列,设置大小
        this.queue = new ArrayBlockingQueue<>(2);
        this.excutor = new ThreadPoolExecutor(
                2,
                8,
                60,
                TimeUnit.SECONDS,
                this.queue,
                threadFactory,
//                daemonThreadFactory,
                //线程池对拒绝任务的处理策略,直接放弃,会抛异常
//                new ThreadPoolExecutor.AbortPolicy()
                //线程池对拒绝任务的处理策略,如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行程序(如果再次失败,则重复此过程)
                new ThreadPoolExecutor.DiscardOldestPolicy()
        );
    }

    public void execute(Runnable r) {
        excutor.execute(r);
    }

    /**
     * 没有返回值的多线程
     *
     * @param args
     */
    public static void main(String[] args) {
        ThreadDemo threadDemo = new ThreadDemo();
        int count = 0;
        for (int i = 0; i < 20; i++) {
            try {
                threadDemo.execute(new MyRunnable(i));
            } catch (Exception e) {
                e.printStackTrace();
                count++;
            }
        }

        try {
            log.info("queue size:" + threadDemo.queue.size());
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        log.info("Reject task: " + count);

        threadDemo.excutor.shutdown();
    }

    /**
     * 有返回值的多线程
     *
     * @throws ExecutionException
     * @throws InterruptedException
     */
    @Test
    public void testMyCallBack() throws ExecutionException, InterruptedException {
        ThreadDemo threadDemo = new ThreadDemo();

        for (int i = 0; i < 10; i++) {
            MyCallBack myCallBack = new MyCallBack(i);
            Future submit = threadDemo.excutor.submit(myCallBack);
            Object o = submit.get();
            log.info(o.toString());
        }
    }
}

class MyRunnable implements Runnable {
    private int num = 0;

    public MyRunnable(int num) {
        this.num = num;
    }

    @Override
    public void run() {
        System.out.println(num + " OK!");
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class MyCallBack implements Callable {
    private String result = "  任务执行,耗时:";

    private int num;

    public MyCallBack(int num) {
        this.num = num;
    }

    @Override
    public Object call() throws Exception {
        Date dateTmp1 = new Date();
        Thread.sleep(1000);
        Date dateTmp2 = new Date();
        long time = dateTmp2.getTime() - dateTmp1.getTime();
        return num + result + time + "ms";
    }
}

 

你可能感兴趣的:(java)