Java中实现优先级任务调度器

Java【优先级队列】详细图解 / 模拟实现 + 【PriorityQueue】常用方法介绍 优先级队列并不是像普通普通的队列那样永远遵从先进先出, 而是有优先级的, 出队时让优先级高的先出队上篇文章说过, 二叉树是一种逻辑结构, 物理结构上可以是顺序存储, 也可以是链式存储, 而堆就是在顺序存储的二叉树上做了调整PriorityQueue底层使用了堆这种数据结构堆的概念: 如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中,并满足:Ki 阅读详情

网上找了下java里的异步任务调度器,很多,但没有基于优先级队列的(或者我没发现),于是我写了一个。

前方干货预警!

一共四个文件。
AloneTask.java(带有优先级的任务类)
ComparableThreadPoolExecutor.java(带有比较器的线程池)
NamedThreadFactory.java(可命名线程池,这个不是必须的)
Scheduler.java(调度器,找了网上的一份改了下)

AloneTask这里加了很多项目里的东西,比如用了spring的依赖注入来获取任务类名,还有slf4j的日志工具,还有自己写的Util空判断器。遇上异常可以删掉那块或者留言,核心的地方不会有异常。

import java.lang.reflect.Method;
import java.util.concurrent.Callable;

import org.slf4j.Logger;

public class AloneTask<T> implements Callable<T>, Comparable<AloneTask<T>>, Runnable {
	private static final Logger logger = Loggers.asyncLogger;

	Object service;
	String method;
	Object[] params;
	String trace;//调用任务的堆栈,性能较低,上线时注释 TODO
	int priority;

	public AloneTask(T service, String method, int priority, Object... params) {
		super();
		if (service instanceof String) {
			this.service = Config.ctx.getBean((String) service);
		} else {
			this.service = service;
		}
		this.priority = priority;
		this.method = method;
		this.params = params;
		this.trace = Util.getCallStack();
	}

	@Override
	@SuppressWarnings("unchecked")
	public T call() throws Exception {
		if (service == null || Util.isEmpty(method)) {
			logger.error("参数异常,无法完成任务.调用堆栈:" + this.trace);
			return null;
		}
		long startTime = System.currentTimeMillis();
		T future = (T) getMethod().invoke(this.service, this.params);
		long useTime = (startTime - System.currentTimeMillis()) / 1000;
		if (useTime > 10) {
			logger.warn("call cost time too long,time " + useTime + "s,task method:" + this.method);
		}
		return future;
	}
	
	@Override
	public void run() {
		if (service == null || Util.isEmpty(method)) {
			logger.error("参数异常,无法完成任务.调用堆栈:" + this.trace);
			return;
		}
		long startTime = System.currentTimeMillis();
		try {
			getMethod().invoke(this.service, this.params);
		} catch (Exception e) {
			logger.error("异步任务异常,任务所在线程:" + Thread.currentThread().getName() + " 异常详细信息:\n" + e.getMessage() + "\n任务调用堆栈:" + this.trace);
		}
		long useTime = (startTime - System.currentTimeMillis()) / 1000;
		if (useTime > 10) {
			logger.warn("call cost time too long,time " + useTime + "s,task method:" + this.method);
		}
	}

	/*
	 * 获取被调用的方法
	 */
	private Method getMethod() {
		Method m = null;
		try {
			Class<?>[] paramsClass = new Class[this.params.length];
			for (int i = 0; i < this.params.length; i++) {
				paramsClass[i] = this.params[i].getClass();
			}
			m = this.service.getClass().getDeclaredMethod(this.method, paramsClass);
		} catch (Exception e) {
			Method[] allMethods = this.service.getClass().getDeclaredMethods();
			for (Method mRec : allMethods) {
				if (mRec.getName().equals(this.method)) {
					Class<?>[] methodParamsTypes = mRec.getParameterTypes(); // 找到同名函数的参数类型
					if (methodParamsTypes.length == this.params.length) {
						boolean flag = true;
						for (int i = 0; i < methodParamsTypes.length; i++) {
							if (null != this.params[i]) {
								if (!match(this.params[i], methodParamsTypes[i])) {
									flag = false;
									break;
								}
							}
						}
						if (flag) {
							m = mRec;
							break;
						}
					}
				}
			}
		}

		if (null == m) {
			logger.info(String.format("未找到[%s]的[%s]方法完成任务.", this.service.getClass().toString(), this.method));
		} else {
			m.setAccessible(true);// 设置访问域以允许访问private和protected方法
		}
		return m;
	}

	/**
	 * 判断参数类型是否匹配
	 * 
	 * @param c
	 *            参数类型
	 * @param pc
	 *            方法参数类型
	 * @return
	 */
	private boolean match(Object p, Class<?> pc) {
		boolean isMatch = true;
		if (pc.isPrimitive()) { // 方法参数是基本类型
			if (!pc.equals(getPrimitiveClass(p.getClass()))) {
				isMatch = false;
			}
		} else {
			if (!pc.isInstance(p)) {
				isMatch = false;
			}
		}
		return isMatch;
	}

	private static Class<?> getPrimitiveClass(Class<?> c) {
		Class<?> pc = null;
		if (c.equals(Long.class)) {
			pc = long.class;
		} else if (c.equals(Integer.class)) {
			pc = int.class;
		} else if (c.equals(Double.class)) {
			pc = double.class;
		} else if (c.equals(Float.class)) {
			pc = float.class;
		} else if (c.equals(Short.class)) {
			pc = short.class;
		} else if (c.equals(Byte.class)) {
			pc = byte.class;
		} else if (c.equals(Character.class)) {
			pc = char.class;
		} else if (c.equals(Boolean.class)) {
			pc = boolean.class;
		}
		return pc;
	}

	//比较优先级
	@Override
	public int compareTo(AloneTask<T> o) {
		if (this.priority < o.priority) {
			return -1;
		}
		if (this.priority > o.priority) {
			return 1;
		}
		return 0;
	}
}

ComparableThreadPoolExecutor.java

public class ComparableThreadPoolExecutor extends ThreadPoolExecutor {

	public ComparableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
			BlockingQueue<Runnable> workQueue) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
	}

	public ComparableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
			BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
	}

	public ComparableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
			BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
	}

	public ComparableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
			BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
	}

	@Override
	protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
		return new ComparableFutureTask<>(runnable, value);
	}

	@Override
	protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
		return new ComparableFutureTask<>(callable);
	}

	protected class ComparableFutureTask<V> extends FutureTask<V> implements Comparable<ComparableFutureTask<V>> {
		private Object object;

		public ComparableFutureTask(Callable<V> callable) {
			super(callable);
			object = callable;
		}

		public ComparableFutureTask(Runnable runnable, V result) {
			super(runnable, result);
			object = runnable;
		}

		@Override
		@SuppressWarnings({ "unchecked", "rawtypes" })
		public int compareTo(ComparableFutureTask<V> o) {
			if (this == o) {
				return 0;
			}
			if (o == null) {
				return -1; // 内容为null的任务排在队尾
			}
			if (object != null && o.object != null) {
				if (object.getClass().equals(o.object.getClass())) {
					if (object instanceof Comparable) {
						return ((Comparable) object).compareTo(o.object);
					}
				}
			}
			return 0;
		}
	}
}

NamedThreadFactory.java 给线程起个名字方便debug和管理。

public class NamedThreadFactory implements ThreadFactory {
	
	private AtomicInteger order = new AtomicInteger(0);
	
	private String name;
	
	public NamedThreadFactory(String name) {
		this.name = name;
	}

	@Override
	public Thread newThread(Runnable r) {
		Thread thread = new Thread(r);
		thread.setName(name + "  ORDER:" + order.getAndIncrement());
		return thread;
	}
	
}

Scheduler.java,我预先放了5个优先级,可以外部定义(记得改ComparableThreadPoolExecutor的compareTo)。

public class Scheduler {
	private static final Scheduler instance = new Scheduler();
	private static ExecutorService executorServie;
	
	private static final int CORE_POOL_SIZE = 10;
	private static final int MAXIMUM_POOL_SIZE = 10;

	private Scheduler() {
		executorServie = new ComparableThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, 1, 
														  TimeUnit.SECONDS, new PriorityBlockingQueue<Runnable>(),
														  new NamedThreadFactory("Scheduler任务调度器子线程"));
	}

	@Bean(name = "Bmall.Scheduler", initMethod = "init", destroyMethod = "shutdown")
	public static Scheduler getInstance() {
		return instance;
	}
	
	public void init() {
		
	}

	public void shutdown() {  
		executorServie.shutdown();
    }

	/**
	 * 将任务存入任务队列中。支持存private和protected方法。
	 * @param service 类名(必须注册为spring的bean)或其实例
	 * @param method 方法名
	 * @param priority 优先级
	 * @param params 参数
	 */
	@SuppressWarnings("unchecked")
	public <T> void call(T service, String method, PRIORITY priority, T... params) {
		Runnable runnable = new AloneTask<T>(service, method, priority.getValue(), params);
		executorServie.execute(runnable);
	}
	
	/**
	 * 将任务存入任务队列中并返回future。支持存private和protected方法。
	 * @param service 类名(必须注册为spring的bean)或其实例
	 * @param method 方法名
	 * @param priority 优先级
	 * @param params 参数
	 * @return future可用于回调
	 */
	@SuppressWarnings("unchecked")
	public <T> Future<T> callBack(T service, String method, PRIORITY priority, T... params){
		Callable<T> callback = new AloneTask<T>(service, method, priority.getValue(), params);
		Future<T> future = executorServie.submit(callback);
		return future;
	}
	
	public enum PRIORITY {
		/** 最低级别 */
		LOWEST(5),
		
		/** 需要一段时间后执行的级别 */
		LOW(4),
		
		/** 默认级别*/
		NORMAL(3),
		
		/** 很可能马上就需要执行的级别 */
		HIGH(2),
		
		/** 需要立即执行的级别*/
		HIGHEST(1);
		
		private final int value;

	    // 构造器默认也只能是private, 从而保证构造函数只能在内部使用
	    private PRIORITY(int value) {
	        this.value = value;
	    }

	    public int getValue() {
	        return value;
	    }
	}

}

具体使用方法:(将print任务以中优先级放入队列中执行)

public void print(String str) {
	System.out.println(str);
}

public static void main(String[] args) {
	Scheduler.getInstance().call(this, "print", PRIORITY.NORMAL, "打印的内容");
}

需要注意的是Scheduler里的call()方法的异常会直接打印,而callback()里的异常会被存在返回值中。

java实现任务调度 今天为什么要写点东西呢,因为我觉得自己现在开始有意思的去培养出写代码之外的能力,所以给自己定下一个目标,每个星期至少写点东西来。 聊些什么呢?那就聊自己的状态吧!因为觉得最近的状态自己特别二,干什么事情都特二,除了工作上的事情外,工作中还是需要严谨的。 最近自己没事就喜欢笑,没有什么事情好笑,但就是笑起来了,还笑个不停,晚上九点钟离开公司的那一刻,人立马就二起来了,莫名其妙的笑起来。然后做事情也是 阅读详情

相关推荐

爬取Aliexpress网站的商品数据,保存至excel表格

小爬虫实现商品数据分类爬取-Aliexpress数据爬虫实现

饭饭的博客 7571

java 任务调度timer_Java定时任务调度

前言基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行任务。TimerTimer定义A facility for threads to schedule tasks for future execution in a background thread. Tasks may be scheduled for one-time execution, or for repeated execu...

weixin_35473090的博客 173

Aruba CX交换机VSX配置实战:如何避免脑裂导致的网络中断(含详细命令)

本文提供Aruba CX交换机VSX配置的实战指南,重点讲解如何通过构建高可靠的ISL链路聚合与独立隔离的Keepalive链路,有效避免网络脑裂风险。文章包含详细的命令步骤,从基础配置到高级故障排查,帮助网络工程师构建坚如磐石的高可用核心网络,确保业务流量零中断。

weixin_29231725的博客 170

用JAVA实现优先级调度算法

参考文章: https://blog.youkuaiyun.com/qq_41900081/article/details/85275060 https://blog.youkuaiyun.com/abc1498880402/article/details/80372441 一、实验目的 在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。当就绪进程个数大于处理机数时,就必须依照某种策略来决定哪些进程优先占用处理机。本实验模拟在单处理机情况下的进程调度,帮助学生加深了解进程调度的工作。 二、实验内容 设计一个按优先级.

DIGUA的博客 2598

人脸关键点定义汇总

前几天看一份代码临时需要找49个人脸关键点位置定义的图片发现怎么百度都搜不到,最后幸好谷歌可以使用了就用谷歌搜到了。所以在这里汇总一下我所知道的人脸关键点的定义和相关的一点东西,以备不时之需。 68个关键点 最常用的工具是Dlib,网址:http://dlib.net/ dlib的68个特征点检测算法是ERT算法【1】 使用dlib检测68个特征点的python示例见:http://dlib.n...

程序媛 7642

从硬件异常到代码救赎:RH850内存访问错误(MAE)的深层诊断与艺术

本文深入探讨瑞萨RH850微控制器的内存访问错误(MAE)诊断与解决方法。针对程序跑飞和Flash Driver交互中的潜在陷阱,提供系统性硬件异常分析框架和防御性编程实践,帮助嵌入式开发者从底层机制到代码层面有效预防和修复MAE问题,提升系统稳定性。

pytorch8learner的博客 195

java设定优先级_java多线程如何设置优先级

从thread类中,我们可以看到类中预先定义了三个优先级。通过getpriority可以看到新建线程的默认等级。public class ExtendsThread {public static void main(String[] args) {MyThread c = new MyThread("线程C");int priority = c.getPriority();System.out.p...

weixin_35895753的博客 985

Triton推理服务器实战:如何为PaddleOCR的ONNX模型配置动态批处理和并发推理

本文详细介绍了如何使用Triton推理服务器为PaddleOCR的ONNX模型配置动态批处理和并发推理,以提升GPU利用率和推理性能。通过实战案例和参数调优指南,帮助开发者解决高并发场景下的性能瓶颈问题,实现从实验室到生产环境的高效部署。

weixin_42527160的博客 426

java数据结构-顺序循环队列与顺序优先级队列及进程管理应用

顺序循环队列 class SeqQueue { static final int defaultSize=10; int front; int rear; int maxSize; Object[] value; int count; public SeqQueue() { initiate(defaultSiz...

m0_37942202的博客 336

离散数学 --- 图论基础 --- 图的同构,通路与回路,可达性与最短通路

同一个图(这里的图是抽象的数学定义)可以有不同的图形表示方法1.重数:两点之间的平行边的个数1.得到 n!的过程,一个图中的一个结点在另一个图中对应的结点有n种可能(黄框中定义的图来讨论),这个对应好后下一个结点有 n - 1 种可能,再下一个有n-2种,直到最后一个为1,所有可能的结果就等于 n * (n - 1) *(n - 2)*....*1 = n!2.虽然说找对应结点很困难,但不是没有规律可循的。比如1.两个相互对应的结点的度数要相同;

qq_51947882的博客 7440

RPA与旅游与酒店行业自动化实战案例

1. 背景介绍 1.1 旅游与酒店行业的挑战 旅游与酒店行业是一个高度竞争的市场,企业需要不断提高服务质量、降低成本、提高效率以保持竞争力。在这个过程中,企业面临着诸多挑战,如客户需求多样化、市场变化快速、人力资源成本高昂等。为了应对这些挑战,企业需要寻求新的技术手段来提高运营效率。

AI天才研究院 615

Java 实现多线程任务调度器:动态任务分配与优先级管理

Java 实现多线程任务调度器:动态任务分配与优先级管理

安 1153

UNET改进77:全网首发-添加CFBlock |

本文介绍了在UNet模型中集成CFBlock注意力机制的实现方法。主要分为三个步骤:1) 创建CFBlock模块,包含卷积注意力机制和MLP;2) 在UNet连接处添加注意力模块;3) 在卷积层中嵌入注意力机制。具体实现包括:定义Conv、MLP和ConvolutionalAttention等基础模块,构建CFBlock核心结构;在UNet跳跃连接处插入注意力模块;将注意力机制整合到DoubleConv和Down模块中。该方法通过在不同位置引入注意力机制,可有效提升模型的特征提取能力。代码实现使用PyTor

AIcurator的博客 388

任务调度器的类型及其用途是什么?如何在Java中同步多个线程的操作?

在OOP中,代码通常按功能模块(类和方法)进行组织,然而有些功能性需求,如日志记录、事务管理、权限控制等,会跨越多个模块并在很多地方出现,这被称为横切关注点,因为它们“切割”了多个类和方法的垂直职责结构。任务调度器(Task Scheduler)在不同的操作系统和上下文中可以有不同的实现方式和用途,但总的来说,它的核心功能是在多个并发任务之间进行选择并决定下一个要执行的任务。这样可以在不改变原有业务逻辑代码的情况下,插入或织入这些关注点,从而减少代码的重复,提高代码的复用性和可维护性。

WangYaolove1314的博客 1799

利用pytorch长短期记忆网络LSTM实现股票预测分析

长短时记忆网络(Long Short Term Memory Network, LSTM),是一种改进之后的循环神经网络,可以解决RNN无法处理长距离的依赖的问题,目前比较流行。LSTM主要就是加入了三个门控:第一个开关遗忘门:负责控制继续保存长期状态c;第二个开关输入门:负责控制把即时状态输入到长期状态c;第三个开关输出门:负责控制是否把长期状态c作为当前的LSTM的输出。

优快云 精品推荐 1万+

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

php多线程 yield,PHP yield 协程实战—“多线程”任务调度器

引想试试,用纯PHP代码,不依赖第三方拓展就实现"多线程"么。像 Java 那样使用 setPriority() 影响各个"线程"的被调用几率,使用join()等待其他线程结束;在sleep期间让出CPU占用,到点再回到该"线程";像 Golang 一样,用channel在协程之间通信~三部曲续接上回书,讲完了 yield 基本用法,这篇文章,带大家来实战一下,目标:手把手教会你用 yield 做...

weixin_34410564的博客 314

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

php中多线程中run方法没有输出echo_PHP yield 协程实战—“多线程”任务调度器

引想试试,用纯 PHP 代码,不依赖第三方拓展就实现"多线程"么。像 Java 那样使用 setPriority() 影响各个"线程"的被调用几率,使用 join() 等待其他线程结束;在 sleep 期间让出 CPU 占用,到点再回到该"线程";像 Golang 一样,用 channel 在 协程 之间通信~续接上回书,讲完了 yield 基本用法,这篇文章,带大家来实战一下,目标:手把手教会你...

weixin_42137723的博客 308

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

并发编程-基础

让一个线程停止,另外一个线程多跑一点,可以调用yield和设置线程优先级yield调用yield会让当前线程从Running进入Runnable就绪状态,然后调度执行其他线程。具体的实现依赖于操作系统的任务调度器。线程优先级会提示(hint)调度器优先调度该线程,但它仅仅是一个提示,调度器可以忽略它。如果CPU比较忙,那么优先级高的线程会获得更多的时间片,但CPU闲时,优先级几乎没作用。

2302_80490510的博客 948

【Java数据结构】队列详解与经典 OJ 题目实战

文章摘要 本文系统讲解了Java队列的核心知识与应用,包括FIFO特性、队列分类(普通队列、双端队列、优先级队列等)及常用实现类(LinkedList、ArrayDeque等)。通过6道经典OJ题目(如用栈实现队列、二叉树层次遍历等)详细解析队列的实战应用,涵盖解题思路、Java代码实现及复杂度分析。内容由浅入深,从基础理论到算法实践,帮助开发者掌握队列数据结构及其在BFS、任务调度等场景的应用技巧。

手心朝下的博客 1085

PriorityQueue的使用

import java.util.Comparator; import java.util.PriorityQueue; public class TestPriorityQueue {     /* result:       component:zookeeper, priority:0       component:hdfs, priority:1      

kellyzly的专栏 509

Java/Android中的优先级任务队列的实践

本篇文章适用于Java和Android开发者,会从实现一个最简单的队列过渡到实现一个带有优先级的队列,使用生活中最常见的的例子结合讲解,保准你可以掌握基本的队列原理。

布莱克‌ 10万+

并发编程指南之定制并发类

Java 并发API提供许多接口和类来实现并发应用程序。它们提供底层(low-level)机制,如Thread类、Runnable或Callable接口、或synchronized关键字。同样也提供高级(high-level)机制,如Executor框架和Java 7 发布的Fork/Join框架。尽管这样,你可能发现你自己开发一个程序时,没有一个java类能满足你的需求。在这种情况下,你也许需要...

车晋强的专栏 180

Java~大根堆的构建与动态维护:从初始化到高效插入删除

本文详细介绍了Java中大根堆的构建与动态维护,包括初始化、高效插入和删除操作。通过向下调整和向上调整算法,实现O(log n)时间复杂度的优先级管理,适用于任务调度等实时系统。文章结合代码示例,深入解析了堆的核心原理与实战应用。

efc123456的博客 429

JAVA实现基于多线程的分布式任务调度系统

JAVA实现基于多线程的分布式任务调度系统

安 509

Java 实现高效并发任务调度器设计与实践

本文详细介绍了 Java 并发任务调度器的设计与实现,从基础技术储备,到架构设计、代码实现,再到性能优化与扩展方向,形成完整的解决方案。通过合理运用线程池、任务包装与调度逻辑,可构建高效、可靠的并发任务调度系统,满足多样化业务场景需求。在实际项目中,可根据具体业务特点,进一步调整优化调度器,使其更好地服务于应用程序,提升整体性能与稳定性。

m0_69128338的博客 1196
上一篇: 关于在Java中如何更简单的使用google protobuf
盯紧你自己
博客等级 码龄14年 1粉丝 2原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值