线程的创建
1.继承
private static class ThreadDemo1 extends Thread{
@Override
public void run() {
System.out.println("ThreadDemo1");
}
}
2.实现接口
private static class ThreadDemo2 implements Runnable{
@Override
public void run() {
System.out.println("ThreadDemo2");
}
}
3,使用线程池
//
ExecutorService service = Executors.newFixedThreadPool(1);
service.submit(()->{
System.out.println(Thread.currentThread().getId());
});
ExecutorService 线程池对象
Executors 线程池工厂类,可以产生多种线程池,主要有以下几种
//创建单一线程的线程池
1. ExecutorService service1 = Executors.newSingleThreadExecutor();
//创建固定数量的线程池
2. ExecutorService service2 = Executors.newFixedThreadPool(1);
//创建带缓存的线程池
3. ExecutorService service3 = Executors.newCachedThreadPool();
//创建定时调度的线程池
4. ExecutorService service4 = Executors.newScheduledThreadPool(1);
//创建流式线程池
5. ExecutorService service5 = Executors.newWorkStealingPool(1);
--- 详解1. newSingleThreadExecutor
-- 我们进入源码看一下:
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
--可以明显看到,这里是调用了 FinalizableDelegatedExecutorService ,参数是一个线程池对象
FinalizableDelegatedExecutorService -> DelegatedExecutorService -> AbstractExecutorService
-> ExecutorService
--上面是 FinalizableDelegatedExecutorService 的继承关系,可以看出来它是 ExecutorService 的子类,然后我们分析参数
-- new ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,)
corePoolSize 核心线程数,最少的线程数,该线程池最少会维持的线程数目,这里面的都是Alive
maximumPoolSize 最多线程数
keepAliveTime (maximunPoolSize-corePoolSize)中空闲线程的存活时间
unit 存活时间的单位
workQueue 对于没有分配到执行资源的线程,进入阻塞队列等待资源的分配
workQueue 队列类型
前提:ThreadPool 可以接收的任务数=corePoolSize(以下称C) + Queue(以下称Q) + (maximumPoolSize-corePoolSize)(以下称M) 并且是从前向后依次开启
--数组形式,使用这个队列会线程到达corePoolSize后,将新的线程存入队列,队列满后继续开启线程,直到达到maximumPoolSize数目,总数量是 C+Q+M 即CQM
ArrayBlockingQueue (java.util.concurrent)
--这个队列仅能存放一个任务,但是需要被立刻执行,所以可以理解总数量为 Q+M 即 QM
SynchronousQueue (java.util.concurrent)
--链表形式,在链表里面可以理解为Q是无限的,总数量 CQM=CQ 所以 M无效
LinkedBlockingQueue (java.util.concurrent)
--使用PriorityBlockingQueue队列,可以理解为链表形式,所以是无限的,又因为要使用优先级属性,所以使用这个队列,线程数就只能是corePoolSize的数目,上面的几种队列都是使用的先进先出,这种队列则是根据优先级来进行排序出队。总数量C
PriorityBlockingQueue (java.util.concurrent)
--链表形式,根据任务的延时来获取出队任务,总数量是 C
DelayedWorkQueue in ScheduledThreadPoolExecutor (java.util.concurrent)
DelayQueue (java.util.concurrent)
//有了上面的知识,我们就可以解读 newSingleThreadExecutor 的线程池属性了?
newSingleThreadExecutor(1个核心线程,最多1个线程,存活0,单位是微秒,链表形式队列)
-- 详解2. newFixedThreadPool
--源码如下:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
//有了上面的知识,我们就可以解读 newFixedThreadPool 的线程池属性了?
newFixedThreadPool(n个核心线程,最多n个线程,存活0,单位是微秒,链表形式队列)
-- 详解3. newCachedThreadPool
--源码如下:
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
//有了上面的知识,我们就可以解读 newCachedThreadPool 的线程池属性了?
newFixedThreadPool(0个核心线程,最多MAX_VALUE个线程,存活80,单位是秒,SynchronousQueue队列)
-- 详解4. newScheduledThreadPool
--源码如下:
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
--继续向下看 得到结果
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}
//有了上面的知识,我们就可以解读 newScheduledThreadPool 的线程池属性了?
newScheduledThreadPool(0个核心线程,最多MAX_VALUE个线程,存活0,单位是纳秒,DelayedWorkQueue队列)
补充知识:
ThreadPoolExecutor完整参数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
ThreadFactory threadFactory 使用哪个线程工厂
ThreadFactory (java.util.concurrent)
URLLoaderThreadFactory in NetworkContext (com.sun.webkit.network)
DaemonThreadFactory in Engine (com.sun.xml.internal.ws.api.pipe)
DaemonThreadFactory in WSServiceDelegate (com.sun.xml.internal.ws.client)
ComInvoker in Win32ShellFolderManager2 (sun.awt.shell)
DefaultThreadFactory in Executors (java.util.concurrent) 默认
CustomThreadFactory in SocketStreamHandle (com.sun.webkit.network)
QuantumThreadFactory in QuantumRenderer (com.sun.javafx.tk.quantum)
CustomThreadFactory in WatchdogTimer (com.sun.webkit)
DaemonThreadFactory in Monitor (javax.management.monitor)
Anonymous in RecompilableScriptFunctionData (jdk.nashorn.internal.runtime)
Anonymous in LaunchDownload (com.sun.javaws)
Anonymous in RuntimeUtil (sun.rmi.runtime)
Anonymous in TCPTransport (sun.rmi.transport.tcp)
Anonymous in SwingWorker (javax.swing)
handler 拒绝策略,当任务大于maximumPoolSize时,这个线程池会怎么处理新的请求
handler类型
//抛弃最老的任务,接受新任务
DiscardOldestPolicy in ThreadPoolExecutor (java.util.concurrent)
//抛弃任务,报告异常
AbortPolicy in ThreadPoolExecutor (java.util.concurrent)
//用当前线程池的线程去执行任务,会停一个一个线程
CallerRunsPolicy in ThreadPoolExecutor (java.util.concurrent)
//抛弃任务,不报告异常
DiscardPolicy in ThreadPoolExecutor (java.util.concurrent)