ThreadPoolExecutor 线程池几个核心的参数

使用线程池的方式有许多种,可以使用JDK自带的Executors类中创建线程池的方式。通过源码可以看出都是使用new ThreadPoolExecutor来创建线程池的。

import com.google.common.collect.Lists;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import lombok.Builder;
import lombok.Data;

/**
 * @author :wangyongkang
 * @date :Created in 2019/12/17 5:28 下午
 * @description: 自定义一个线程池
 * @modified By:
 * @version:
 */
public class CustomThreadPool {

  /**
   * corePoolSize:核心线程数,即时是空闲的也不会被回收,除非设置allowCoreThreadTimeOut=true才会被回收。
   * maximumPoolSize:最大线程数。
   * keepAliveTime:超过核心线程的其它线程的存活时间。
   * unit:超过核心线程的其它线程的存活时间单位。
   * workQueue:当任务塞满了所有的线程,任务会被存放在queue中。
   * threadFactory:创建新线程使用的Factory。
   * handler:当任务数量达到了(maxPoolSize+queue)的数量,其它的任务不会处理,会调用rejectedExecution()方法。
   */
  private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,
      4,
      10,
      TimeUnit.SECONDS,
      new LinkedBlockingDeque<>(2),
      new MyThreadPoolFactory(),
      new MyRejectedExecutionHandler());

  public static void main(String[] args) {
    new CustomThreadPool().submitMethod();
  }

  /**
   * 整个执行流程
   * 1、一开始线程池中没有线程。
   * 2、有任务进来,便会启动core pool size。
   * 3、当超过core pool size,便会将任务放到queue中。
   * 4、当超过core pool size + queue,启动max pool size来处理任务。
   * 5、当超过core pool size + queue,启动(max pool size)-(core pool size)来处理任务。
   * 6、当超过max pool size + queue,调用rejectedExecution()方法。
   * 7、所有任务处理完成,(max pool size)-(core pool size)会被回收。
   * <p>
   * 注意: 如果BlockingDeque的Capacity没有设置大小。则只会使用core pool size去处理任务。
   */
  public void submitMethod() {
    System.out.println("threads pool size:" + threadPoolExecutor.getPoolSize());
    //任务List<MyTask>
    List<MyTask> myTaskList = Lists.newArrayList();
    //任务结果List<Future<MyTask>>,返回线程的一些信息
    List<Future<MyTask>> futureList = Lists.newArrayList();
    int i = 0;
    while (i < 10) {
      myTaskList.add(MyTask.builder().name("task" + (i++)).build());
    }
    myTaskList.forEach(o -> {
      futureList.add(threadPoolExecutor.submit(o));
    });
    System.out.println("threads pool size:" + threadPoolExecutor.getPoolSize());
    System.out.println("futureList-->:" + futureList);
    try {
      Thread.sleep(20000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    System.out.println("threads pool size:" + threadPoolExecutor.getPoolSize());
  }
}

/**
 * 自定义ThreadPoolFactory
 * 抄一下Executors是怎么写的
 */
class MyThreadPoolFactory implements ThreadFactory {

  private static final AtomicInteger poolNumber = new AtomicInteger(1);
  private final ThreadGroup group;
  private final AtomicInteger threadNumber = new AtomicInteger(1);
  private final String namePrefix;

  MyThreadPoolFactory() {
    SecurityManager s = System.getSecurityManager();
    group = (s != null) ? s.getThreadGroup() :
        Thread.currentThread().getThreadGroup();
    namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-";
  }

  @Override
  public Thread newThread(Runnable r) {
    Thread t = new Thread(group, r,
        namePrefix + threadNumber.getAndIncrement(),
        0);
    if (t.isDaemon()) {
      t.setDaemon(false);
    }
    if (t.getPriority() != Thread.NORM_PRIORITY) {
      t.setPriority(Thread.NORM_PRIORITY);
    }
    return t;
  }
}

/**
 * 自定义RejectedExecutionHandler
 * 抄一下Executors是怎么写的
 */
class MyRejectedExecutionHandler implements RejectedExecutionHandler {

  @Override
  public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    try {
      throw new RejectedExecutionException(
          "Task " + r.toString() + " rejected from " + e.toString());
    } catch (RejectedExecutionException re) {
      System.out.println(re.getMessage());
      re.printStackTrace();
    }
  }

}

/**
 * 自定义Callable
 */
@Data
@Builder
class MyTask implements Callable<MyTask> {

  private String name;

  @Override
  public MyTask call() {
    System.out.println("ThreadName:" + Thread.currentThread().getName() + ",taskName:" + name);
    try {
      Thread.sleep(2000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    return this;
  }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章