《Java知识应用》Java-线程池(ScheduledExecutorService)
先回顾一下,Runnable 的使用方法。
package demo.knowledgepoints.scheduledtask.run; /***
* 线程类
*/
public class ThreadTest implements Runnable { public static int ticket = 9; @Override
public void run() {
try {
System.out.println("当前线程:"+Thread.currentThread().getName());
while(true){
synchronized (this) {
Thread.sleep(1000L);
if (this.ticket > 0) {
ticket--;
System.out.println(Thread.currentThread().getName() + ":出售一张票!");
System.out.println("剩余票量:" + ticket);
} else {
System.out.println("没有票了!");
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package demo.knowledgepoints.scheduledtask.run;
public class ThreadMemo {
public static void main(String[] args) {
ThreadTest threadTest1 =new ThreadTest();
new Thread(threadTest1).start();
new Thread(threadTest1).start();
}
}
每一个线程的启动,都会占用资源,一个线程5分钟执行一次,一个线程10分钟执行。两个线程分别启动则需要启动两个线程。线程越多需要启动的线程就越多。性能浪费就越大。
于是我们会考虑,5分钟的线程,我们5分钟到了去唤醒一个线程,执行一次,然后再让其睡眠,10分钟的线程也如初,就可以省下同一时间的线程数,线程越多效果越是明显。
正好:java提供了方法:ScheduledExecutorService
我们就根据ScheduledExecutorService来实现一个线程池:
package demo.knowledgepoints.scheduledtask.inf;
import demo.knowledgepoints.scheduledtask.iml.ScheduledTaskTot;
public interface ScheduledService {
/**
* 添加一个任务
* @author Eric
* @date 16:14 2019/3/12
* @params runnable
* @params taskId
* @params initialDelay 初次等待 毫秒
* @params delay 间隔时间 毫秒(不延迟)
* @throws
* @return boolean
**/
boolean addFixedTask(ScheduledTaskTot scheduledTaskTot);
/**
* 添加一个任务
* @author Eric
* @date 16:14 2019/3/12
* @params runnable
* @params taskId
* @params initialDelay 初次等待 毫秒
* @params delay 间隔时间 毫秒(延迟)
* @throws
* @return boolean
**/
boolean addTask(ScheduledTaskTot scheduledTaskTot);
/**
* 修改一个任务
* @author Eric
* @date 16:14 2019/3/12
* @params runnable
* @params taskId
* @params initialDelay 初次等待 毫秒
* @params delay 间隔时间 毫秒
* @throws
* @return boolean
**/
boolean updateTask(ScheduledTaskTot scheduledTaskTot) throws InterruptedException;
/**
* 移除一个任务
* @author Eric
* @date 16:14 2019/3/12
* @params taskId
* @throws
* @return boolean
**/
boolean remove(String taskId);
/**
* 关闭定时任务服务
* @author Eric
* @date 16:14 2019/3/12
* @throws
* @return void
**/
void shutdown();
/**
* 初始化定时任务服务
* @author Eric
* @date 16:15 2019/3/12
* @throws
* @return void
**/
void init() throws Exception;
}
package demo.knowledgepoints.scheduledtask.inf;
public interface TaskServcesInf {
public void Test1();
public void Test2();
public void Test3();
}
package demo.knowledgepoints.scheduledtask.iml; import demo.knowledgepoints.scheduledtask.inf.ScheduledService; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; public class ScheduledServiceIml implements ScheduledService { private static ScheduledExecutorService service; private static Map<String, ScheduledFuture> futureMap = new ConcurrentHashMap<>(); @Override
public boolean addFixedTask(ScheduledTaskTot scheduledTaskTot) {
if (futureMap.get(scheduledTaskTot.getTaskId()) != null) {
return false;
}
// 这里将任务放入定时服务中
ScheduledFuture<?> scheduledFuture = service.scheduleAtFixedRate(scheduledTaskTot.getRunnable()
, scheduledTaskTot.getInitialDelay(), scheduledTaskTot.getDelay(), TimeUnit.MILLISECONDS); futureMap.put(scheduledTaskTot.getTaskId(),scheduledFuture);
return true;
} @Override
public boolean addTask(ScheduledTaskTot scheduledTaskTot) {
if (futureMap.get(scheduledTaskTot.getTaskId()) != null) {
return false;
}
// 这里将任务放入定时服务中
ScheduledFuture<?> scheduledFuture = service.scheduleWithFixedDelay(scheduledTaskTot.getRunnable()
, scheduledTaskTot.getInitialDelay(), scheduledTaskTot.getDelay(), TimeUnit.MILLISECONDS); futureMap.put(scheduledTaskTot.getTaskId(),scheduledFuture); return true;
} @Override
public boolean updateTask(ScheduledTaskTot scheduledTaskTot) throws InterruptedException {
if (futureMap.get(scheduledTaskTot.getTaskId()) == null) {
return false;
}
// 先停止
remove(scheduledTaskTot.getTaskId()); // 再添加
addTask(scheduledTaskTot);
return true;
} @Override
public boolean remove(String taskId) {
if (futureMap.get(taskId) == null) {
return false;
}
ScheduledFuture scheduledFuture = futureMap.get(taskId);
scheduledFuture.cancel(false);
futureMap.remove(taskId);
return true;
} @Override
public void shutdown() {
service.shutdown();
} @Override
public void init() throws Exception {
service = Executors.newScheduledThreadPool(8);
}
}
package demo.knowledgepoints.scheduledtask.iml; import demo.untils.StringUntil;
import demo.untils.TimeUtil; import java.lang.reflect.Method; public class ScheduledTaskTot { /** 需要执行方法的线程 */
Runnable runnable;
/** 唯一的id用于增删改 */
String taskId;
/** 定时任务需要执行的方法类 */
String className;
/** 定时任务需要执行的方法 */
String method;
/** 首次执行等待时间 */
long initialDelay;
/** 间隔时间 */
long delay; /**
* 创建一个需要定时的任务
* @param taskId
* @param className
* @param method
* @param initialDelay
* @param delay
* @param beginTime(执行开始时间)
* @param endTime(执行结束时间)
*/
public ScheduledTaskTot(String taskId, String className, String method, long initialDelay, long delay, String beginTime, String endTime) {
this.taskId = taskId;
this.className = className;
this.method = method;
this.initialDelay = initialDelay;
this.delay = delay;
// 在创建实例的时候,初始化线程类,通过反射获取要执行的类与方法,目前没有加参数,大家可以自行扩展
runnable = () -> {
System.out.println("---------------------------------");
try {
//在beginTime 到 endTime 之间才执行。
if(StringUntil.isNotBlank(beginTime) && StringUntil.isNotBlank(endTime)){
if(TimeUtil.getTimeMillis(beginTime) - System.currentTimeMillis() >= 0 && TimeUtil.getTimeMillis(endTime) - System.currentTimeMillis() <= 0){
Class<?> cls = Class.forName(className);
Method method1 = cls.getMethod(method);
method1.invoke(cls.newInstance(),null);
}
}else{
Class<?> cls = Class.forName(className);
Method method1 = cls.getMethod(method);
method1.invoke(cls.newInstance(),null);
}
} catch (Exception e) {
e.printStackTrace();
}
};
} public Runnable getRunnable() {
return runnable;
} public void setRunnable(Runnable runnable) {
this.runnable = runnable;
} public String getTaskId() {
return taskId;
} public void setTaskId(String taskId) {
this.taskId = taskId;
} public String getClassName() {
return className;
} public void setClassName(String className) {
this.className = className;
} public String getMethod() {
return method;
} public void setMethod(String method) {
this.method = method;
} public long getInitialDelay() {
return initialDelay;
} public void setInitialDelay(long initialDelay) {
this.initialDelay = initialDelay;
} public long getDelay() {
return delay;
} public void setDelay(long delay) {
this.delay = delay;
}
}
package demo.knowledgepoints.scheduledtask.iml;
import demo.knowledgepoints.scheduledtask.inf.TaskServcesInf;
public class TaskServcesIml implements TaskServcesInf {
public void Test1(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Test1------------------------");
}
public void Test2(){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Test2------------------------");
}
public void Test3(){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Test3------------------------");
}
}
package demo.knowledgepoints.scheduledtask.iml;
public class ScheduledServiceTest {
public static void main(String[] args) {
ScheduledServiceIml scheduledServiceIml = new ScheduledServiceIml();
try {
scheduledServiceIml.init();
scheduledServiceIml.addTask(new ScheduledTaskTot("T0001","demo.knowledgepoints.scheduledtask.iml.TaskServcesIml","Test1",1000L,5000L,null,null));
scheduledServiceIml.addTask(new ScheduledTaskTot("T0002","demo.knowledgepoints.scheduledtask.iml.TaskServcesIml","Test2",1000L,5000L,null,null));
scheduledServiceIml.addTask(new ScheduledTaskTot("T0003","demo.knowledgepoints.scheduledtask.iml.TaskServcesIml","Test3",1000L,5000L,null,null));
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出结果:

参考资料:https://blog.csdn.net/money9sun/article/details/88575704?tdsourcetag=s_pctim_aiomsg
如有疑问请留言,每一个都会及时回复。
《Java知识应用》Java-线程池(ScheduledExecutorService)的更多相关文章
- Java多线程系列--“JUC线程池”03之 线程池原理(二)
概要 在前面一章"Java多线程系列--“JUC线程池”02之 线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明.内容包括:线程池示例参考代 ...
- Java多线程-新特性-线程池
Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利.为了编写高效稳定可靠的多线程程序 ...
- 深入理解Java自带的线程池和缓冲队列
前言 线程池是什么 线程池的概念是初始化线程池时在池中创建空闲的线程,一但有工作任务,可直接使用线程池中的线程进行执行工作任务,任务执行完成后又返回线程池中成为空闲线程.使用线程池可以减少线程的创建和 ...
- Java:多线程,线程池,用Executors静态工厂生成常用线程池
一: newSingleThreadExecutor 创建一个单线程的线程池,以无界队列方式运行.这个线程池只有一个线程在工作(如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它.)此线程池 ...
- 【转】线程池体系介绍及从阿里Java开发手册学习线程池的正确创建方法
jdk1.7中java.util.concurrent.Executor线程池体系介绍 java.util.concurrent.Executor : 负责线程的使用与调度的根接口 |–Execut ...
- java高并发之线程池
Java高并发之线程池详解 线程池优势 在业务场景中, 如果一个对象创建销毁开销比较大, 那么此时建议池化对象进行管理. 例如线程, jdbc连接等等, 在高并发场景中, 如果可以复用之前销毁的对 ...
- Java并发编程:线程池ThreadPoolExecutor
多线程的程序的确能发挥多核处理器的性能.虽然与进程相比,线程轻量化了很多,但是其创建和关闭同样需要花费时间.而且线程多了以后,也会抢占内存资源.如果不对线程加以管理的话,是一个非常大的隐患.而线程池的 ...
- Java并发编程:线程池的使用
Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...
- Java多线程系列--“JUC线程池”06之 Callable和Future
概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...
- Java多线程系列--“JUC线程池”02之 线程池原理(一)
概要 在上一章"Java多线程系列--“JUC线程池”01之 线程池架构"中,我们了解了线程池的架构.线程池的实现类是ThreadPoolExecutor类.本章,我们通过分析Th ...
随机推荐
- 【Linux系列】Centos 7安装 Nginx(三)
目的 为了下面的Laravel部署,本篇开始安装Nignx服务器. 防火墙设置 在物理主机上查看nginx是否安装成功,需要开放虚拟机的80端口. 用cmder登录到虚拟机 firewall-cmd ...
- Res2net:多尺度骨干网络结构
<Res2Net: A New Multi-scale Backbone Architecture> 来自:南开大学程明明组 论文:https://arxiv.org/abs/1904.0 ...
- 继上篇-jquery ajax提交 本篇用ajax提交的数据去数据库查询
上篇讲到如何用jquery ajax提交数据至后台,后台接收并返回给ajax.https://www.cnblogs.com/tiezhuxiong/p/11943328.html 今天我们把数据传到 ...
- Java并发之synchronized关键字和Lock接口
欢迎点赞阅读,一同学习交流,有疑问请留言 . GitHub上也有开源 JavaHouse,欢迎star 引用 当开发过程中,我们遇到并发问题.怎么解决? 一种解决方式,简单粗暴:上锁.将千军万马都给拦 ...
- Java工作流引擎全局变量的介绍
关键词:工作流快速开发平台 工作流流设计 业务流程管理 asp.net 开源工作流bpm工作流系统 java工作流主流框架 自定义工作流引擎 在系统中有很多的地方需要用到表达式的地方,这些 ...
- Celery框架实现异步执行任务
Celery 官方 Celery 官网:http://www.celeryproject.org/ Celery 官方文档英文版:http://docs.celeryproject.org/en/la ...
- mac 终端高亮显示~
针对terminal采用bash模式: 编辑 ~/.bash_profile, 加入以下代码: export CLICOLOR=1 export LSCOLORS=gxfxaxdxcxegedabag ...
- 处理器CPU天梯图,显卡天梯图(性能排名图)
自己网上找的几个图,仅供参考,买电脑可以看看了~
- node.js多进程架构
node.js是单进程应用,要充分利用多核cpu的性能,就需要用到多进程架构. 作为web服务器,不能多个进程创建不同的socket文件描述符去accept网络请求, 有经验的同学知道,如果端口被占用 ...
- powerline字体安装
安装命令 git clone https://github.com/powerline/fonts ./install.sh 了解powerline ->美化自己的命令行环境,增加漂亮的状态行, ...