优秀的手机游戏下载!
首页 ScheduledThreadPoolExecutor删除任务,该怎么解决

ScheduledThreadPoolExecutor删除任务,该怎么解决

发布时间:2024-01-11 00:20:34 编辑:手游帝 浏览:382

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

看了下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类, 此里面有个: --…
查看详情
相关资讯
猜你喜欢