线程并发学习
线程并发学习—-核心概念(转载)
线程并发学习—-线程阻塞(sleep、wait、notifyAll、notify、join)
线程并发学习—-线程阻塞(synchronized)
线程并发学习—-线程阻塞(lock)
线程并发学习—-Thread、Runnable、Callable
线程并发学习—-队列(Queue)
spring学习—-线程池
java中一些锁概念整理(转载)
简介
创建和销毁线程需要时间、资源
线程池可以达到这样的效果:一个线程执行完任务之后,继续去执行下一个任务,不被销毁,这样线程利用率提高了。
参数
- corePoolSize:线程池的大小。线程池创建之后不会立即去创建线程,而是等待线程的到来。当当前执行的线程数大于改值是,线程会加入到缓冲队列;
- maximumPoolSize:线程池中创建的最大线程数;
- keepAliveTime:空闲的线程多久时间后被销毁。默认情况下,改值在线程数大于corePoolSize时,对超出corePoolSize值得这些线程起作用。
- unit:TimeUnit枚举类型的值,代表keepAliveTime时间单位 spring默认使用TimeUnit.SECONDS,不支持配置
TimeUnit.DAYS; //天
TimeUnit.HOURS; //小时
TimeUnit.MINUTES; //分钟
TimeUnit.SECONDS; //秒
TimeUnit.MILLISECONDS; //毫秒
TimeUnit.MICROSECONDS; //微妙
TimeUnit.NANOSECONDS; //纳秒
- workQueue:阻塞队列,用来存储等待执行的任务,决定了线程池的排队策略,spring线程池默认LinkedBlockingQueue,具体使用见createQueue方法
ArrayBlockingQueue基于数组的先进先出队列,此队列创建时必须指定大小
LinkedBlockingQueue基于链表的先进先出队列,如果创建时没有指定此队列大小,则默认为Integer.MAX_VALUE;
SynchronousQueue这个队列比较特殊,它不会保存提交的任务,而是将直接新建一个线程来执行新来的任务
- threadFactory:线程工厂,是用来创建线程的。默认new Executors.DefaultThreadFactory();
- handler:线程拒绝策略。当创建的线程超出maximumPoolSize,且缓冲队列已满时,新任务会拒绝
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy://主线程会自己去执行该任务,不会等待线程池中的线程去执行
线程池原理
类图ThreadPoolExecutor
继承抽象类 实现ExecutorService接口 实现Executor接口 Executor为顶层接口只定义了一个execute方法
两个执行方法
execute 没有返回值
execute()方法是Executor中声明的方法,在ThreadPoolExecutor有了具体的实现,该方法向线程池提交一个任务,由线程池执行,从源码可以看成改方法没有返回值
submit 有返回值
submit()方法是ExecutorService中声明的方法,在AbstractExecutorService中进行了实现,从源码可以看出该方法底层也是调用execute()方法,并且该方法会返回一个Future
spring配置
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="10" />
<property name="maxPoolSize" value="50" />
<property name="keepAliveSeconds" value="180" />
<property name="queueCapacity" value="80" />
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
</property>
</bean>
注:Spring中的线程池是由ThreadPoolTaskExecutor类来实现的。该类的实现原理最终也是调用了java中的ThreadPoolExecutor类中的一些方法,详情见源码
如何合理配置线程池大小
一般需要根据任务的类型来配置线程池大小:
如果是CPU密集型任务,就需要尽量压榨CPU,参考值可以设为 NCPU+1
如果是IO密集型任务,参考值可以设置为2*NCPU
个人觉得线程池大小参考并发数配置,具体还是要看具体情况 系统负载、资源利用率
源码
Executor
public interface Executor {
void execute(Runnable command);
}
public interface ExecutorService extends Executor {
void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();
boolean isTerminated();
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException;
<T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException;
<T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
线程池核心类ThreadPoolExecutor
public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueue<Runnable> var6) {
this(var1, var2, var3, var5, var6, Executors.defaultThreadFactory(), defaultHandler);
}
public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueue<Runnable> var6, ThreadFactory var7) {
this(var1, var2, var3, var5, var6, var7, defaultHandler);
}
public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueue<Runnable> var6, RejectedExecutionHandler var7) {
this(var1, var2, var3, var5, var6, Executors.defaultThreadFactory(), var7);
}
public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueue<Runnable> var6, ThreadFactory var7, RejectedExecutionHandler var8) {
this.ctl = new AtomicInteger(ctlOf(-536870912, 0));
this.mainLock = new ReentrantLock();
this.workers = new HashSet();
this.termination = this.mainLock.newCondition();
if(var1 >= 0 && var2 > 0 && var2 >= var1 && var3 >= 0L) {
if(var6 != null && var7 != null && var8 != null) {
this.corePoolSize = var1;
this.maximumPoolSize = var2;
this.workQueue = var6;
this.keepAliveTime = var5.toNanos(var3);
this.threadFactory = var7;
this.handler = var8;
} else {
throw new NullPointerException();
}
} else {
throw new IllegalArgumentException();
}
}
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
private boolean addWorker(Runnable firstTask, boolean core) {
//省略部分代码
.....
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
//执行Thread的start方法启动线程,执行run方法
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
//创建Thread 默认使用DefalutThreadFactory
this.thread = getThreadFactory().newThread(this);
}
Executors
static class DefaultThreadFactory 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;
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = "pool-" +
poolNumber.getAndIncrement() +
"-thread-";
}
//创建Thread对象
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;
}
}
AbstractExecutorService类
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
/**
* Returns a {@code RunnableFuture} for the given callable task.
*
* @param callable the callable task being wrapped
* @param <T> the type of the callable's result
* @return a {@code RunnableFuture} which, when run, will call the
* underlying callable and which, as a {@code Future}, will yield
* the callable's result as its result and provide for
* cancellation of the underlying task
* @since 1.6
*/
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
/**
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
/**
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public <T> Future<T> submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}
/**
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
spring线程池实现类ThreadPoolTaskExecutor 部分源码,从源码可以看出spring的线程池最终也是通过实现ThreadPoolExecutor 来实现的
public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport implements AsyncListenableTaskExecutor, SchedulingTaskExecutor {
private final Object poolSizeMonitor = new Object();
private int corePoolSize = 1;
private int maxPoolSize = 2147483647;
private int keepAliveSeconds = 60;
private int queueCapacity = 2147483647;
private boolean allowCoreThreadTimeOut = false;
private ThreadPoolExecutor threadPoolExecutor;//
protected ExecutorService initializeExecutor(ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
BlockingQueue queue = this.createQueue(this.queueCapacity);
//初始化ThreadPoolExecutor
ThreadPoolExecutor executor = new ThreadPoolExecutor(this.corePoolSize, this.maxPoolSize, (long)this.keepAliveSeconds, TimeUnit.SECONDS, queue, threadFactory, rejectedExecutionHandler);
if(this.allowCoreThreadTimeOut) {
executor.allowCoreThreadTimeOut(true);
}
this.threadPoolExecutor = executor;
return executor;
}
//使用那种队列,默认LinkedBlockingQueue
protected BlockingQueue<Runnable> createQueue(int queueCapacity) {
return (BlockingQueue)(queueCapacity > 0?new LinkedBlockingQueue(queueCapacity):new SynchronousQueue());
}
public ThreadPoolExecutor getThreadPoolExecutor() throws IllegalStateException {
Assert.state(this.threadPoolExecutor != null, "ThreadPoolTaskExecutor not initialized");
return this.threadPoolExecutor;
}
//executor实际就是执行ThreadPoolExecutor的execute方法
public void execute(Runnable task) {
ThreadPoolExecutor executor = this.getThreadPoolExecutor();
try {
executor.execute(task);
} catch (RejectedExecutionException var4) {
throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, var4);
}
}
参考文档
https://www.cnblogs.com/lsr-mark/p/7815871.html
https://www.cnblogs.com/dolphin0520/p/3932921.html