2022-05-28_线程任务的推送学习笔记

20220528_线程任务的推送学习笔记

1概述

本文学习一下线程及线程池任务的推送及处理。

1.1项目架构

image-20220528211255303.png

2代码示例

2.1ExecuteTask

package com.kikop.mycocurrent.iextask;

/**
 * @author kikop
 * @version 1.0
 * @project myconcurrent
 * @file ExecuteTask
 * @desc
 * @date 2021/4/26
 * @time 9:30
 * @by IDE: IntelliJ IDEA
 */
public interface ExecuteTask {
    void execute();
}

2.2MyThreadPoolHelper

package com.kikop.mycocurrent.utils;

import com.kikop.mycocurrent.iextask.ExecuteTask;

import java.util.concurrent.*;

/**
 * @author kikop
 * @version 1.0
 * @project myconcurrent
 * @file MyThreadPoolHelper
 * @desc
 * @date 2021/4/26
 * @time 9:30
 * @by IDE: IntelliJ IDEA
 */
public class MyThreadPoolHelper {

    // 停止线程池的等待时间
    private final long AWAIT_TIMEMS_ON_STOP = 5000;


    // 线程池
    // 任务二级缓存
    // executorServicePool,LinkedBlockingQueue
    private ExecutorService executorServicePool = null;

    private void init() {

        executorServicePool = new ThreadPoolExecutor(10, 10,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue(), new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) { // 好处就是易于问题错误排查
                return new Thread(r, "myfutureTaskSchedulerThread-Pool-" + r.hashCode());
            }
        });
    }

    private void stop() {

        // 2.停止线程池
        // 2.1.停止线程池新任务的接收
        executorServicePool.shutdown();

        // 2.2.等待指定的时间,ms
        try {
            // Wait a while for existing tasks to terminate.
            if (!executorServicePool.awaitTermination(AWAIT_TIMEMS_ON_STOP, TimeUnit.MILLISECONDS)) {
                executorServicePool.shutdownNow();
                // Wait a while for tasks to respond to being cancelled.
                if (!executorServicePool.awaitTermination(AWAIT_TIMEMS_ON_STOP, TimeUnit.MILLISECONDS)) {
//                    log.warn(String.format("%s didn't terminate!", executor));
                }
            }
        } catch (InterruptedException ie) {
            ie.printStackTrace();
            // (Re-)Cancel if current thread also interrupted.
            executorServicePool.shutdownNow();
            // Preserve interrupt status.
            Thread.currentThread().interrupt();
        }
    }

    // 对外暴露
    // 对象实例的创建在内部完成,便于外部使用
    private static MyThreadPoolHelper myThreadPoolHelper = new MyThreadPoolHelper();

    public static void toStart() {
        myThreadPoolHelper.init();
    }

    public static void toStop() {
        myThreadPoolHelper.stop();
    }

    /**
     * 添加任务
     *
     * @param executeTask
     */
    public static void addTask(ExecuteTask executeTask) {
        myThreadPoolHelper.executorServicePool.execute(new ExecuteTaskRunnable(executeTask));
    }

    /**
     * ConvertExecuteTask2ExecuteTaskRunnable
     */
    static class ExecuteTaskRunnable implements Runnable {

        ExecuteTask executeTask;

        ExecuteTaskRunnable(ExecuteTask executeTask) {
            this.executeTask = executeTask;
        }

        /**
         * 条件到某一个具体的线程池里
         */
        public void run() {
            executeTask.execute();
        }
    }
}

2.3MyFutureTaskSchedulerThread

package com.kikop.mycocurrent;

import com.kikop.mycocurrent.iextask.ExecuteTask;
import com.kikop.mycocurrent.utils.MyThreadPoolHelper;
import com.kikop.util2.MyDateUtil;

import java.util.concurrent.ConcurrentLinkedQueue;


/**
 * @author kikop
 * @version 1.0
 * @project myconcurrent
 * @file MyFutureTaskSchedulerThread
 * @desc
 * @date 2021/4/26
 * @time 9:30
 * @by IDE: IntelliJ IDEA
 */
public class MyFutureTaskSchedulerThread extends Thread {

    // private final Logger logger = Logger.getLogger(this.getClass());


    // 静态变量
    // 类加载器加载中创建初始化
    // 任务执行
    private static MyFutureTaskSchedulerThread myFutureTaskSchedulerThreadInstance =
            new MyFutureTaskSchedulerThread("t-myFutureTaskSchedulerThread");

    // 控制 MyFutureTaskSchedulerThread的启停
    private static volatile boolean toStop = false;


    // 任务执行过程中线程休眠时间
    private long sleepTimeMs = 1000;


    // 当前线程的任务队列,获取的任务转换提交到线程池
    // 任务一级缓存
    private ConcurrentLinkedQueue executeTaskQueue = new ConcurrentLinkedQueue();

    /**
     * 在线程中运行
     */
    public MyFutureTaskSchedulerThread(String threadName) {
        super(threadName);
        MyThreadPoolHelper.toStart();
        this.start();
    }

    /**
     * 线程中调度
     */
    @Override
    public void run() {

        while (!toStop) {
            System.out.println(String.format("%s,%s,begin run...",
                    MyDateUtil.getCurrentDateStrByDefaultFormat(),
                    Thread.currentThread().getName()));

            fetchTask(); // 处理任务
            threadSleep(sleepTimeMs);

            System.out.println(String.format("%s,%s,end run!",
                    MyDateUtil.getCurrentDateStrByDefaultFormat(),
                    Thread.currentThread().getName()));

        }
    }

    private void threadSleep(long timeMs) {
        try {
            sleep(timeMs);
        } catch (InterruptedException e) {
//            logger.error(e);
            e.printStackTrace();
        }
    }

    /**
     * 同步处理任务队列,检查其中是否有任务
     */
    private void fetchTask() {
        try {
            ExecuteTask executeTask;
            while (executeTaskQueue.peek() != null) { // 先判读是否有数据
                executeTask = executeTaskQueue.poll(); // 有数据
                processTask(executeTask);
            }
        } catch (Exception e) {
//            logger.error(e);
        }
    }

    /**
     * 执行任务到线程池操作
     *
     * @param executeTask
     */
    private void processTask(ExecuteTask executeTask) {
        System.out.println(String.format("%s,%s,begin processTask...",
                MyDateUtil.getCurrentDateStrByDefaultFormat(), Thread.currentThread().getName()));
        MyThreadPoolHelper.addTask(executeTask);
        System.out.println(String.format("%s,%s,end processTask!",
                MyDateUtil.getCurrentDateStrByDefaultFormat(), Thread.currentThread().getName()));
    }

    /**
     * 添加任务
     *
     * @param executeTask
     */
    public static void addTask(ExecuteTask executeTask) {
        myFutureTaskSchedulerThreadInstance.executeTaskQueue.add(executeTask);
    }


    /**
     * stopTask
     * 1.停止全局静态线程
     * 2.停止线程池
     */
    public static void stopTask() {

        // 1.通过变量优雅的停止全局静态线程
        toStop = true;

        // 2.停止线程池
        MyThreadPoolHelper.toStop();
    }


}

2.4测试MyFutureTaskSchedulerThreadTest

/**
 * Created by 尼恩 at 疯狂创客圈
 */

package com.kikop.mycocurrent;


//import org.apache.log4j.Logger;

import com.kikop.util2.MyDateUtil;

import java.util.concurrent.TimeUnit;


/**
 * @author kikop
 * @version 1.0
 * @project myconcurrent
 * @file MyFutureTaskSchedulerThread
 * @desc
 * @date 2021/4/26
 * @time 9:30
 * @by IDE: IntelliJ IDEA
 */
public class MyFutureTaskSchedulerThreadTest {

    public static void main(String[] args) throws InterruptedException {

        MyFutureTaskSchedulerThread.addTask(() -> {
            System.out.println(String.format("%s,%s,begin exec task...",
                    MyDateUtil.getCurrentDateStrByDefaultFormat(), Thread.currentThread().getName()));

            System.out.println(String.format("%s,%s,end exec task!",
                    MyDateUtil.getCurrentDateStrByDefaultFormat(), Thread.currentThread().getName()));

        });

        TimeUnit.SECONDS.sleep(3);
        MyFutureTaskSchedulerThread.stopTask();
    }
}

参考

你可能感兴趣的:(2022-05-28_线程任务的推送学习笔记)