多线程(线程池)

一、Java通过Executors提供四种线程池,分别为:

newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待,表示同一时刻只能有这么大的并发数
newScheduledThreadPool 创建一个定时线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

二、ScheduledThreadPoolExecutor用于定时任务,这里的定时意义在于:

指定延时后执行任务。
周期性重复执行任务。

接着分析ScheduledThreadPoolExecutor源码,从类声明开始

类声明

public class ScheduledThreadPoolExecutor
        extends ThreadPoolExecutor
        implements ScheduledExecutorService {
    //……
}     

ScheduledThreadPoolExecutor继承了ThreadPoolExecutor,实现了ScheduledExecutorService。在线程池的基础上,实现了可调度的线程池功能。上一篇文章已经详细介绍了ThreadPoolExecutor,这里我们先看下ScheduledExecutorService的源码:

ScheduledExecutorService

//可调度的执行者服务接口
public interface ScheduledExecutorService extends ExecutorService {

    //指定时延后调度执行任务
    public ScheduledFuture schedule(Runnable command,
                                       long delay, TimeUnit unit);

    //指定时延后调度执行任务
    public  ScheduledFuture schedule(Callable callable,
                                           long delay, TimeUnit unit);

    //指定时延后开始执行任务,以后每隔period的时长再次执行该任务
    public ScheduledFuture scheduleAtFixedRate(Runnable command,
                                                  long initialDelay,
                                                  long period,
                                                  TimeUnit unit);

    //指定时延后开始执行任务,以后任务执行完成后等待delay时长,再次执行任务
    public ScheduledFuture scheduleWithFixedDelay(Runnable command,
                                                     long initialDelay,
                                                     long delay,
                                                     TimeUnit unit);
}

ScheduledExecutorService实现了ExecutorService,并增加若干定时相关的接口。其中schedule方法用于单次调度执行任务。这里主要理解下后面两个方法。
• scheduleAtFixedRate:该方法在initialDelay时长后第一次执行任务,以后每隔period时长,再次执行任务。注意,period是从任务开始执行算起的。开始执行任务后,定时器每隔period时长检查该任务是否完成,如果完成则再次启动任务,否则等该任务结束后才再次启动任务,看下图示例。


多线程(线程池)_第1张图片
image.png

• scheduleWithFixDelay:该方法在initialDelay时长后第一次执行任务,以后每当任务执行完成后,等待delay时长,再次执行任务,看下图示例。


image.png

碰到过问题:ScheduledExecutorService 如何结束掉一条子线程任务
Java 程序员都知道我们可以用 ScheduledExecutorService 按照一定的间隔或频率执行任务,但这个任务一旦开始,就只能到 ThreadPool shutdown 了才能结束。如何按照一定条件,在不终止整个线程池的情况下结束任务,可以通过抛出异常去结束掉。

private  Map map = new HashMap();
public void sendMessage(final String message) throws IOException{
         scheduledService.scheduleAtFixedRate(new Runnable() {

            public void run() {
                Integer integer = 0;
                if (map.containsKey(message)) {
                    integer = map.get(message);
                    integer ++;
                    map.put(message, integer);
                } else {
                    map.put(message, integer);
                }
                try {
                    System.out.println("ThreadSendSocket:" + integer + "\t" + message + "\t" + new Date());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if(map.get(message) == 10) {
//                  scheduledService.shutdownNow();   /停止线程池的操作
                    System.out.println("kill Thread" + message);
                    throw new RuntimeException("kill Thread" + message);
                }
            }
        }, 0, 2000, TimeUnit.MILLISECONDS);
}

ScheduledThreadPoolExecutor参考:https://blog.csdn.net/luanmousheng/article/details/77816412

你可能感兴趣的:(多线程(线程池))