java线程池(1)初识线程池
对于用了java很久的程序员来说,java线程池一般都不陌生。但是对于刚开始使用java的人,对java线程池的了解可能就不是那么多充分了。
首先,我来说一下为什么需要线程池,多线程不就可以了吗?什么时候需要我就创建一个线程。不就可以了吗?
如果我们先要了解线程池就必须首先了解线程这个东西!线程是什么?
- 线程是最小的执行单位。
- 线程是进程的轻量实体
- 独立调度和分派的基本单位
- 共享进程资源,有独立的栈
为什么多线程可以提高效率呢???其实,在最初的时代是没有线程这个概念的!比如60年代是没有线程的只有进程。到了80年代才有的线程!因为不是所有的任务都是CPU密集型的操作。当任务不是CPU密集型的操作的时候,多线程就起到了作用了。一个线程去执行任务,另外一个线程去做另外的需要CPU的任务。这样可以将CPU的计算能力发挥的更大。
为什么是使用多线程现在大概已经知道了!还有一个问题为什么需要线程池这个东西?线程执行任务的过程有以下几个过程的:
- 创建一个线程到就绪状态(时间需要T1)
- 执行所要执行的任务(时间需要T2)
- 销毁这个线程释放所有占用的资源(时间需要T3)
如果我们没有线程池。那么当我们需要多线程处理的时候,每一次需要的时间都会是T总 = T1 + T2 + T3 ,但是我们有了线程呢?那么创建线程的时间和销毁线程的时间,很多时候就不需要每次都消耗掉了!所以线程池的意义就在这里了!
说了这么多,我们现在来说说java常用的线程池都有哪些呢?大概有以下几种:
- FixedThreadPool
- CachedThreadPool
- SingleThreadPool
- ScheduledThreadPool
下面来一波解释:
FixedThreadPool 是一个固定线程数量的线程池,最多有指定个数的线程来执行任务。只可以指定上限,并不会指定下限。
CachedThreadPool 是一个可以指定线程数量的范围的线程池。线程池在任务队列满的时候回根据指定的上限和下限的差距来增加线程数量。
SingleThreadPool 这里面只有一个线程。它以保证所有的任务,按照你传入的顺序来执行。
ScheduleThreadPool 这里面可以指定你传入的任务,延迟指定时间来执行
现在来分析一下这些线程池的创建吧!
package com.bj.cachedthreadpool;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.concurrent.ThreadFactory;
/**
* 自定义的线程工厂方法类!
* */
@Data
@AllArgsConstructor
public class MyThreadFactory implements ThreadFactory{
private String name;
@Override
public Thread newThread(Runnable r) {
MyThread thread = new MyThread(r,name,"test");
return thread;
}
}
ExecutorService executorService = Executors.newFixedThreadPool(5, new MyThreadFactory("Fixed"));
new ThreadPoolExecutor(5,5,0, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
Executors.newCachedThreadPool(new MyThreadFactory("Cache"));
new ThreadPoolExecutor(0,Integer.MAX_VALUE,0, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
Executors.newSingleThreadExecutor(new MyThreadFactory("Single"));
new ThreadPoolExecutor(1,1,0, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
Executors.newScheduledThreadPool(5,new MyThreadFactory("scheduled"));
new ThreadPoolExecutor(5,5,0, TimeUnit.SECONDS, new ScheduledThreadPoolExecutor.DelayedWorkQueue());
这8行代码是一样的作用!奇数行是暴露给我们的方法。下面是真实的调用。
这么看来线程池的创建好像没什么好厉害的哈。就这一个不过传入的参数不一样,仅此而已。
现在是时候看看线程池的工作模式了!
这里可以清晰的看到有一个核心池和最大池!下面来是几个线程池的情况!
- 如果核心池大小和最大一样就是FixedThreadPool
- 如果核心池大小小于最大池大小就是CacheThreadPool
- 如果核心池和最大池大小都是1那么久是singleThreadPool
- 如果传入一个延迟队列,就是ScheduledThreadPool。
好了,今天的线程池创建就说到这里。下一期会讲讲线程池的具体工作流程和原理!敬请期待哟!
最后附上代码
https://github.com/yunzhifei/ConcurrentProgramming.git
多谢大家支持!!!