基础知识
java并发
- Java中的多线程是一种抢占式的机制而不是分时机制
- 线程池: 提供一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁的额外开销,提高了响应的速度
- 线程池的体系结构:
java.util.concurrent.Executor 负责线程的使用和调度的根接口
|--ExecutorService 子接口: 线程池的主要接口
|--ThreadPoolExecutor 线程池的实现类
|--ScheduledExceutorService 子接口: 负责线程的调度
|--ScheduledThreadPoolExecutor : 继承ThreadPoolExecutor,实现了ScheduledExecutorService
工具类 : Executors
- Java 5 新增
- Executors是个静态工厂类
- ExecutorService newFixedThreadPool() : 创建固定大小的线程池
- ExecutorService newCachedThreadPool() : 缓存线程池,线程池的数量不固定,可以根据需求自动的更改数量。
- ExecutorService newSingleThreadExecutor() : 创建单个线程池。 线程池中只有一个线程
- ScheduledExecutorService newScheduledThreadPool() : 创建固定大小的线程,可以延迟或定时的执行任务
Java通过Executors提供四种线程池
- newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程(可能存在一直无法回收持续创建新线程)。最大值是在初始化的时候设置,为Integer.MAX_VALUE,可能导致OOM
- newFixedThreadPool:创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
- newScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行。ScheduledThreadPoolExecutor继承自ThreadPoolExecutor,maximumPoolSize值为Integer.MAX_VALUE,可能会导致OOM
- newSingleThreadExecutor: 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
类:ExecutorService
- 特别像一个线程池的一个接口类,通过工具类java.util.concurrent.Executors的静态方法来创建
- 通过 Executors.newXXXThreadPool(n)获取线程池
- 通过 execute(new Runnable(){}) 执行
- 或者 schedule(new Runnable(){}) 执行
- shutdown() :调用后,不可以再submit新的task,已经submit的将继续执行
- shutdownNow() :试图停止当前正执行的task,并返回尚未执行的task的list
- submit(),线程的run()或call()方法自动在一个线程上执行
- submit(),有返回值,而execute没有,submit返回future,可以获取到线程返回的结果数据
- submit(),方便Exception处理,submit不会抛出异常,需要调用返回值Future对象的get方法
- execute(),直接抛出异常,在线程外部无法捕获异常,想要捕获该异常,可以实现UncaughtExceptionHandler接口
- 任务
- Runnable接口的实现类,run()方法执行,没有返回值
- Callable接口的实现类,call()方法执行,有返回值
代码示例
线程类
- 创建一个实现类,根据需要,实现Runnable接口或Callable接口
- 定义自己需要的成员变量,重写run()方法或call()方法
- 示例代码如下:
public class UpdateIndexRunnable implements Runnable {
private Logger log = LoggerFactory.getLogger(UpdateIndexRunnable.class);
private BulkCommitVO bulkCommitVO;
private IIndexService indexEsService = SpringContextHolder.getBean(IIndexService.class);
public UpdateIndexRunnable(BulkCommitVO bulkCommitVO) {
this.bulkCommitVO = bulkCommitVO;
}
@Override
public void run() {
}
}
调用类
- 在调用类,创建静态成员变量
ThreadFactory
和ExecutorService
的对象 - 在方法里直接使用
execute
方法,发起任务 - 示例代码如下:
private static ThreadFactory updateIndexThreadFactory = new ThreadFactoryBuilder()
.setNameFormat("updateIndex-pool-%d").build();
private static ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1024),
updateIndexThreadFactory,new ThreadPoolExecutor.AbortPolicy());
public void updateIndexUsePool(BulkCommitVO bulkCommitVO) {
singleThreadPool.execute(new UpdateIndexRunnable(bulkCommitVO));
}