ScheduledThreadPoolExecutor删除任务,该怎么解决

发布时间:2024-01-11 00:20:34 来源:君肯网

这时候想删除其中一个任务,

看了下API,ScheduledThreadPoolExecutor继承ThreadPoolExecutor类,

此里面有个:

————————————-

boolean remove(Runnable task)

从执行程序的内部队列中移除此任务(如果存在),从而如果尚未开始,则其不再运行。

————————————-

我利用下面方法返回任务列表,执行其contains方法,都表示任务列表里面不包含我的任务。

————————————-

BlockingQueue&ltRunnable getQueue()

返回此执行程序使用的任务队列。

————————————-

——解决的方法——————————————————–

任务列队里的任务实际上对原始的任务做了包装,所以你删除任务的参数必须是你调用scheduleAtFixedRate返回的参数。

——解决的方法——————————————————–

API对此方法有一个说明:

此方法可用作取消方案的一部分。它可能无法移除在放置到内部队列之前已经转换为其他形式的任务。例如,使用 submit 输入的任务可能被转换为维护 Future 状态的形式。

ScheduledThreadPoolExecutor任务超时怎么自动关闭

在实际应用中,有时候我们需要创建一些个延迟的、并具有周期性的任务,比如,我们希望当我们的程序启动后每隔1小时就去做一次日志记录。在JDK中提供了两种方法去创建延迟周期性任务。

Timer

Timer是java.util包下的一个类,在JDK1.3的时候被引入,Timer只是充当了一个执行者的角色,真正的任务逻辑是通过一个叫做TimerTask的抽象类完成的,TimerTask也是java.util包下面的类,它是一个实现了Runnable接口的抽象类,包含一个抽象方法run( )方法,需要我们自己去提供具体的业务实现。

Timer类对象是通过其schedule方法执行TimerTask对象中定义的业务逻辑,并且schedule方法拥有多个重载方法提供不同的延迟与周期性服务。

下面是利用Timer去创建的一个延时周期性任务

import java.text.SimpleDateFormat

import java.util.Date

import java.util.Timer

import java.util.TimerTask

public class TestTimer {

public static void main(String[] args) {

String time = new SimpleDateFormat(“HH:mm:ss”).format(new Date())

System.out.println(“Start time : ” + time)

Timer timer = new Timer()

TimerTask task = new TimerTask() {

@Override

public void run() {

// TODO Auto-generated method stub

String time = new SimpleDateFormat(“HH:mm:ss”).format(new Date())

System.out.println(“Now Time : ” + time)

}

}//end task

timer.schedule(task, 2000, 3000)

}

}

程序的输出:

Start time : 21:36:08

Now Time : 21:36:10

Now Time : 21:36:13

Now Time : 21:36:16

Now Time : 21:36:19

ScheduledThreadPoolExecutor

在JDK1.5的时候在java.util.concurrent并发包下引入了ScheduledThreadPoolExecutor类,引入它的原因是因为Timer类创建的延迟周期性任务存在一些缺陷, ScheduledThreadPoolExecutor继承了ThreadPoolExecutor,并且实现了ScheduledExecutorService接口, ScheduledThreadPoolExecutor也是通过schedule方法执行Runnable任务的。

我们用 ScheduledThreadPoolExecutor来实现和上述Timer一样的功能

import java.text.SimpleDateFormat

import java.util.Date

import java.util.concurrent.ScheduledThreadPoolExecutor

import java.util.concurrent.TimeUnit

public class TestScheduledThreadPoolExecutor {

public static void main(String[] args) {

String time = new SimpleDateFormat(“HH:mm:ss”).format(new Date())

System.out.println(“Start time : ” + time)

ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(5) //创建5个执行线程

Runnable runnable = new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

String time = new SimpleDateFormat(“HH:mm:ss”).format(new Date())

System.out.println(“Now Time : ” + time)

}

}

executor.scheduleWithFixedDelay(runnable, 2, 3, TimeUnit.SECONDS)

}

}

程序的输出:

Start time : 22:12:25

Now Time : 22:12:27

Now Time : 22:12:30

Now Time : 22:12:33

Now Time : 22:12:36

这样看来Timer和 ScheduledThreadPoolExecutor好像没有声明差别,但是 ScheduledThreadPoolExecutor的引入正是由于Timer类存在的一些不足,并且在JDK1.5或更高版本中,几乎没有利用继续使用Timer类,下面说明Timer存在的一些缺点。

单线程

Timer类是通过单线程来执行所有的TimerTask任务的,如果一个任务的执行过程非常耗时,将会导致其他任务的时效性出现问题。而 ScheduledThreadPoolExecutor是基于线程池的多线程执行任务,不会存在这样的问题。

这里我们通过让Timer来执行两个TimerTask任务来说明,其中一个TimerTask的执行过程是耗时的,加入需要2秒。

import java.text.SimpleDateFormat

import java.util.Date

import java.util.Timer

import java.util.TimerTask

public class SingleThreadTimer {

public static void main(String[] args) {

String time = new SimpleDateFormat(“HH:mm:ss”).format(new Date())

System.out.println(“Start time : ” + time)

Timer timer = new Timer()

TimerTask task1 = new TimerTask() {

@Override

public void run() {

// TODO Auto-generated method stub

String time = new SimpleDateFormat(“HH:mm:ss”).format(new Date())

ScheduledThreadPoolExecutor删除任务,该怎么解决

System.out.println(“Task1 time : ” + time)

}

}

TimerTask task2 = new TimerTask() {

@Override

public void run() {

// TODO Auto-generated method stub

try {

Thread.sleep(2000)

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace()

}

String time = new SimpleDateFormat(“HH:mm:ss”).format(new Date())

System.out.println(“task2 time : ” + time)

}

}

timer.schedule(task1, 2000, 1000)

timer.schedule(task2, 2000, 3000)

}

}

这里定义了两个任务,任务1,程序启动2秒后每隔1秒运行一次,任务2,程序启动2秒后,每隔3秒运行1次,然后让Timer同时运行这两个任务

程序的输出如下:

Start time : 22:22:37

Task1 time : 22:22:39

task2 time : 22:22:41

Task1 time : 22:22:41

Task1 time : 22:22:42

task2 time : 22:22:44

Task1 time : 22:22:44

Task1 time : 22:22:45

task2 time : 22:22:47

Task1 time : 22:22:47

Task1 time : 22:22:48

可以分析,无论是任务1还是任务2都没有按照我们设定的预期进行运行,造成这个现象的原因就是Timer类是单线程的。

Timer线程不捕获异常

Timer类中是不捕获异常的,假如一个TimerTask中抛出未检查异常(P.S: java中异常分为两类:checked exception(检查异常)和unchecked exception(未检查异常),对于未检查异常也叫RuntimeException(运行时异常). ),Timer类将不会处理这个异常而产生无法预料的错误。这样一个任务抛出异常将会导致整个Timer中的任务都被取消,此时已安排但未执行的TimerTask也永远不会执行了,新的任务也不能被调度(所谓的“线程泄漏”现象)。

下面就已常见的RuntimeException,ArrayIndexOutOfBoundsException数组越界异常,来演示这个缺点:

import java.text.SimpleDateFormat

import java.util.Date

import java.util.Timer

import java.util.TimerTask

public class TestTimerTask {

public static void main(String[] args) {

System.out.println(new SimpleDateFormat(“HH:mm:ss”).format(new Date()))

Timer timer = new Timer()

TimerTask task1 = new TimerTask() {

@Override

public void run() {

System.out.println(“1: ” + new SimpleDateFormat(“HH:mm:ss”).format(new Date()))

}

}

TimerTask task2 = new TimerTask() {

@Override

public void run() {

int[] arr = {1,2,3,4,5}

try {

Thread.sleep(1000)

} catch (InterruptedException e) {

e.printStackTrace()

}

int index = (int)(Math.random()*100)

System.out.println(arr[index])

System.out.println(“2: ” + new SimpleDateFormat(“HH:mm:ss”).format(new Date()))

}

}

timer.schedule(task1, 2000, 3000)

timer.schedule(task2, 2000, 1000)

}

}

scheduledthreadpoolexecutor 初始化多少个

使用ScheduledThreadPoolExecutor,每隔一个小时去连接指纹机下载考勤记录,有时候指纹机无法返回,导致线程一直在等待,下一个线程无法启动。有没有一个办法,我配置一个超时时间,时间到了,本次任务自动关闭,内存和连接都释放,然后等待下一次的定时到期。

Executors之ScheduledThreadExecutor

通过Executors,可以创建3种类型的ThreadPoolExecutor。

– FixedThreadPool

– SingleThreadExecutor

– CachedThreadPool

1.FixedThreadPool

FixedThreadPool被称为可重用固定线程数的线程池。下面是FixedThreadPool的源代码实现。

public static ExecutorService newFixedThreadPool(int nThreads) {

return new ThreadPoolExecutor(nThreads, nThreads, 0L,

TimeUnit.MILLISECONDS, new LinkedBlockingQueue&ltRunnable&gt())

FixedThreadPool中多余的空闲线程会被立即终止。

FixedThreadPool的execute()运行示意图如下所示。

如果当前运行的线程数小于corePoolSize,则创建新线程来执行任务。

当前运行的线程数等于corePoolSize,将任务加入LinkedBlockingQueue。

线程执行完1中的任务后,会反复从阻塞队列中取任务执行。

ScheduledThreadPoolExecutor 继承自ThreadPoolExecutor实现了ScheduledExecutorService接口。主要完成定时或者周期的执行线程任务。

执行过程:

(1) scheduledExecutorService.schedule(myThread, 5, TimeUnit.SECONDS)

结果:

可以看出主线程启动子线程:scheduledExecutorService.schedule(myThread, 5, TimeUnit.SECONDS)后5S开始thread0,1,2开始执行。scheduledExecutorService.shutdown()//7s 后关闭不再接受执行线程。shutdown()表示scheduledExecutorService关闭不再接受新的线程执行(如果线程已经开始,则等待此线程结束)这里如果没有 Thread.sleep(70000)则所有线程不会执行。while (!scheduledExecutorService.isTerminated()) {//all thread等待结束 这里是主线程等待所有的子线程结束

}

(2)scheduledExecutorService.scheduleWithFixedDelay(myThread, 5, 2, TimeUnit.SECONDS)

结果:

可以看出线程开始延时5后首次执行,以后每隔2S周期执行任务。

以上就是关于ScheduledThreadPoolExecutor删除任务,该怎么解决全部的内容,如果了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

更多相关资讯

这时候想删除其中一个任务, 看了下API,ScheduledThreadPoolExecutor继承ThreadPoolExecutor类,…
查看详情
这时候想删除其中一个任务, 看了下API,ScheduledThreadPoolExecutor继承ThreadPoolExecutor类,…
查看详情
这时候想删除其中一个任务, 看了下API,ScheduledThreadPoolExecutor继承ThreadPoolExecutor类,…
查看详情
相关文章
推荐游戏
风之谷
风之谷
游戏资讯 10.5M
下载
斗罗大陆3
斗罗大陆3
游戏资讯 566.9M
下载
冠军网球
冠军网球
游戏资讯 148.1M
下载
最佳炮手
最佳炮手
游戏资讯 68.1M
下载
如梦下弦月
如梦下弦月
游戏资讯 840.1M
下载
富甲封神传
富甲封神传
游戏资讯 263.0M
下载