使用线程池的方式有许多种,可以使用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;
}
}