20220528_线程任务的推送学习笔记
1概述
本文学习一下线程及线程池任务的推送及处理。
1.1项目架构
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();
}
}