如何中断正在执行IO的 Quartz 作业

Interrupt a Quartz job that doing IO

如果你想中断正在执行IO的 Quartz 作业,在你使用 InterruptibleChannel 时这是可行的。引用一下Oracle链接:实现了这个接口的通道,是可中断的:如果一个线程在一个中断通道阻塞I/O操作,另一个线程能调用阻塞的线程的中断方法。这将导致的通道被关闭,被阻塞的线程收到一个ClosedByInterruptException,设置被阻塞的线程的中断状态。因此,获得自己工作的执行线程的作业计划,能保存供以后使用。当Quartz调度中断作业,你可以再调用该线程的interrupt()方法来停止读/写操作。这里有一个简单的例子:

package demo;

// import statements excluded for brevity

public class MyJob implements InterruptableJob {

  private static Logger    LOG              = LoggerFactory.getLogger(MyJob.class);

  private volatile boolean isJobInterrupted = false;

  private JobKey           jobKey           = null;

  private volatile Thread  thisThread;

  public MyJob() {
  }

  public void execute(JobExecutionContext context) throws JobExecutionException {
    thisThread = Thread.currentThread();
    LOG.info("Thread name of the current job: " + thisThread.getName());

    jobKey = context.getJobDetail().getKey();
    LOG.info("Job " + jobKey + " executing at " + new Date());

    try {
      String fileUrl = "http://d2zwv9pap9ylyd.cloudfront.net/terracotta-3.6.1.tar.gz"; // 59 MB
      String localFile = "terracotta-3.6.1.tar.gz";
      download(fileUrl, localFile);
    } catch (ClosedByInterruptException e) {
      LOG.info("Caught ClosedByInterruptException... exiting job.");
    } catch (IOException e) {
      LOG.info("Caught IOException... exiting job.", e);
    } finally {
      if (isJobInterrupted) {
        LOG.info("Job " + jobKey + " did not complete");
      } else {
        LOG.info("Job " + jobKey + " completed at " + new Date());
      }
    }
  }

  // this method is called by the scheduler
  public void interrupt() throws UnableToInterruptJobException {
    LOG.info("Job " + jobKey + "  -- INTERRUPTING --");
    isJobInterrupted = true;
    if (thisThread != null) {
      // this called cause the ClosedByInterruptException to happen
      thisThread.interrupt();
    }
  }

  private void download(String address, String localFileName) throws ClosedByInterruptException, IOException {
    URL url = new URL(address);
    ReadableByteChannel src = Channels.newChannel(url.openStream());
    WritableByteChannel dest = new FileOutputStream(new File(localFileName)).getChannel();
    try {
      System.out.println("Downloading " + address + " to " + new File(localFileName).getCanonicalPath());
      int size = fastChannelCopy(src, dest);
      System.out.println("Download completed! " + (size / 1024 / 1024) + " MB");
    } finally {
      src.close();
      dest.close();
    }
  }

  // Code copied from http://thomaswabner.wordpress.com/2007/10/09/fast-stream-copy-using-javanio-channels/
  private static int fastChannelCopy(final ReadableByteChannel src, final WritableByteChannel dest) throws IOException {
    final ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024);
    int count = 0;
    int total = 0;
    while ((count = src.read(buffer)) != -1) {
      total += count;
      // prepare the buffer to be drained
      buffer.flip();
      // write to the channel, may block
      dest.write(buffer);
      // If partial transfer, shift remainder down
      // If buffer is empty, same as doing clear()
      buffer.compact();
    }
    // EOF will leave buffer in fill state
    buffer.flip();
    // make sure the buffer is fully drained.
    while (buffer.hasRemaining()) {
      dest.write(buffer);
    }
    return total;
  }
}

这是我的主类,创建Quartz Scheduler和模拟预期的中断。下载将需要大约40秒完成(59MB文件)。为了看到我们的作业确实是在下载过程中中断,我们启动调度然后休息5秒。注:如果您想看到的作业完成,休息了约40秒。

package demo;

import static org.quartz.DateBuilder.nextGivenSecondDate;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;

// other imports excluded for brevity

public class InterruptExample {

  public void run() throws Exception {
    final Logger log = LoggerFactory.getLogger(InterruptExample.class);

    log.info("------- Initializing ----------------------");

    // First we must get a reference to a scheduler
    SchedulerFactory sf = new StdSchedulerFactory();
    Scheduler sched = sf.getScheduler();

    log.info("------- Initialization Complete -----------");

    log.info("------- Scheduling Jobs -------------------");

    // get a "nice round" time a few seconds in the future...
    Date startTime = nextGivenSecondDate(null, 1);

    JobDetail job = newJob(MyJob.class).withIdentity("myJob", "group1").build();

    SimpleTrigger trigger = newTrigger().withIdentity("trigger1", "group1").startAt(startTime)
        .withSchedule(simpleSchedule()).build();

    sched.scheduleJob(job, trigger);

    // start up the scheduler (jobs do not start to fire until
    // the scheduler has been started)
    sched.start();
    log.info("Scheduler thread‘s name: " + Thread.currentThread().getName());
    log.info("------- Started Scheduler -----------------");

    try {
      // if you want to see the job to finish successfully, sleep for about 40 seconds
      Thread.sleep(5 * 1000L);
      // tell the scheduler to interrupt our job
      sched.interrupt(job.getKey());
      Thread.sleep(3 * 1000L);
    } catch (Exception e) {
      e.printStackTrace();
    }

    log.info("------- Shutting Down ---------------------");

    sched.shutdown(true);

    log.info("------- Shutdown Complete -----------------");
  }

  public static void main(String[] args) throws Exception {
    InterruptExample example = new InterruptExample();
    example.run();
  }
}

这是日志,说明我们的作业被intterupted提早退出


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36


INFO [main] ------- Initializing ----------------------

INFO [main] Using default implementation for ThreadExecutor

INFO [main] Job execution threads will use class loader of thread: main

INFO [main] Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl

INFO [main] Quartz Scheduler v.2.1.3 created.

INFO [main] RAMJobStore initialized.

INFO [main] Scheduler meta-data: Quartz Scheduler (v2.1.3) ‘DefaultQuartzScheduler‘ with instanceId ‘NON_CLUSTERED‘

Scheduler class: ‘org.quartz.core.QuartzScheduler‘ - running locally.

NOT STARTED.

Currently in standby mode.

Number of jobs executed: 0

Using thread pool ‘org.quartz.simpl.SimpleThreadPool‘ - with 10 threads.

Using job-store ‘org.quartz.simpl.RAMJobStore‘ - which does not support persistence. and is not clustered.

INFO [main] Quartz scheduler ‘DefaultQuartzScheduler‘ initialized from default resource file in Quartz package: ‘quartz.properties‘

INFO [main] Quartz scheduler version: 2.1.3

INFO [main] ------- Initialization Complete -----------

INFO [main] ------- Scheduling Jobs -------------------

INFO [main] Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.

INFO [main] Scheduler thread‘s name: main

INFO [main] ------- Started Scheduler -----------------

INFO [DefaultQuartzScheduler_Worker-1] Thread name of the current job: DefaultQuartzScheduler_Worker-1

NFO [DefaultQuartzScheduler_Worker-1] Job group1.myJob executing at Mon Apr 16 16:24:40 PDT 2012

Downloading http://d2zwv9pap9ylyd.cloudfront.net/terracotta-3.6.1.tar.gz to S:\quartz-interrupt-demo\terracotta-3.6.1.tar.gz

INFO [main] Job group1.myJob  -- INTERRUPTING --

INFO [DefaultQuartzScheduler_Worker-1] Caught ClosedByInterruptException... exiting job.

INFO [DefaultQuartzScheduler_Worker-1] Job group1.myJob did not complete

ERROR [DefaultQuartzScheduler_Worker-1] Worker thread was interrupt()‘ed.

java.lang.InterruptedException

at java.lang.Object.wait(Native Method)

at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:552)

INFO [main] ------- Shutting Down ---------------------

INFO [main] Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutting down.

INFO [main] Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED paused.

INFO [main] Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutdown complete.

INFO [main] ------- Shutdown Complete -----------------

原文:http://itindex.net/blog/2012/04/23/1335149680608.html

时间: 2024-10-27 10:50:13

如何中断正在执行IO的 Quartz 作业的相关文章

SQL SERVER 2008复制数据库时发生执行SQL Server代理作业错误

1. 情况说明 在利用SQL SERVER数据库复制向导,能够很方便的将一个数据库从一台服务器复制到另一台服务器上,具体操作步骤也十分简单. 不过在实际操作过程常发生“执行SQL SERVER代理作业错误”,点击查看详细会提示“作业失败 有关详细信息,请查看目标服务器上的事件日志”. 2. 处理方案 发生这种情况的一般原因是目标服务器的SQL SERVER代理服务的权限过低.更改代理服务权限为LocalSystem账户即可. A. 开始–程序–SQL SERVER 配置管理器 B. 点击左侧“S

4.Netty执行IO事件和非IO任务

回顾NioEventLoop的run方法流程 IO事件与非IO任务 处理IO事件 处理非IO任务 聚合定时任务到普通任务队列 从普通队列中获取任务 计算任务执行的超时时间 安全执行 计算是否超时 总结 回顾NioEventLoop的run方法流程 上文说到NioEventLoop的run方法可以分为3个步骤: 轮询channel中就绪的IO事件 处理轮询出的IO事件 处理所有任务,也包括定时任务 其中步骤1已在上一节讲述,这里接着讲述下面2个步骤 IO事件与非IO任务 首先看一下在步骤2和步骤3

【淘淘】Quartz作业存储与管理

一.Quartz作业管理和存储方式简介: 作业一旦被调度,调度器需要记住并且跟踪作业和它们的执行次数.如果你的作业是30分钟后或每30秒调用,这不是很有用.事实上,作业执行需要非常准确和即时调用在被调度作业上的execute()方法.Quartz通过一个称之为作业存储(JobStore)的概念来做作业存储和管理. Quartz提供两种基本作业存储类型.第一种类型叫做RAMJobStore,它利用通常的内存来持久化调度程序信息.这种作业存储类型最容易配置.构造和运行.对许多应用来说,这种作业存储已

一个在linux环境执行io操作的bug

今天项目有了一个奇葩的要求...是什么呢 后台上传了视频后,解析其中的时长,和预览图,并拼接在一起,然而,之东西并不是太麻烦,很快写好了,在本地测试后也没有问题,嗯,发布到测试环境后,一个jar包报错,看到这想想今天要加班了\/..\/ 出现的错误是javacv解析视频后,一个jni错误/home/travis/build/javacpp-presets/opencv/cppbuild/linux-x86_64/opencv-3.4.2/modules/videostab/src/frame_s

JAVA结合testng断言verify(断言失败不中断继续执行)

原理: 1.自已构造一个断言类,把Assert.assertEquals给try catch住. 2.利用testng的监听类在测试方法运行结束后进行分析. 代码: 断言类: package com.demo; import java.util.ArrayList; import java.util.List; import org.testng.Assert; public class Assertion { public static boolean flag = true; public

基于ASP.NET MVC(C#)和Quartz.Net组件实现的定时执行任务调度

在之前的文章<推荐一个简单.轻量.功能非常强大的C#/ASP.NET定时任务执行管理器组件–FluentScheduler>和<简单.轻量.功能非常强大的C#/ASP.NET定时调度任务执行管理组件–FluentScheduler之实例篇>中,我们认识和了解了FluentScheduler这款轻量的定时任务调度执行组件.今天再给大家介绍一款关于定时任务调度执行的组件–Quartz.NET,Quartz.Net是Java版Quartz的.NET实现. 相对FluentSchedule

一个简单的使用Quartz和Oozie调度作业给大数据计算平台执行

一,介绍 Oozie是一个基于Hadoop的工作流调度器,它可以通过Oozie Client 以编程的形式提交不同类型的作业,如MapReduce作业和Spark作业给底层的计算平台(如 Cloudera Hadoop)执行. Quartz是一个开源的调度软件,它为任务的调度执行提供了各种触发器以及监听器 下面使用Quartz + Oozie 将一个MapReduce程序提交给Cloudera Hadoop执行 二,调度思路 ①为什么要用Quartz呢?主要是借助Quartz强大的触发器功能.它

LK按作业执行时长优化

新到一家公司,需要折腾点认可出来.然后开始苦逼的优化工作.暂时不吐槽权限问题!!!优化效果优化前,作业历史记录(前30)P图优化前,CPU使用情况有几个作业平均时长2.5~3.5小时,还有很多时长在半小时以上的作业,基本要到11-12点才能完成作业统计.CPU每天7:00-11:00一直维持在比较高的数值.优化后,作业历史记录(前30)P图最近三天的CPU情况最近一天的CPU情况优化后,作业执行时长明显降低,从最近3天执行情况看,9:00前统计作业能够执行完成.服务器CPU高峰时段由之前的7:0

Quartz定时调度jar包的执行Demo分享

1.Quartz简介 ? Quartz框架的核心是调度器.调度器负责管理Quartz应用运行时环境.调度器不是靠自己做所有的工作,而是依赖框架内一些非常重要的部件.Quartz不仅仅是线程和线程管理.为确保可伸缩性,Quartz采用了基于多线程的架构.启动时,框架初始化一套worker线程,这套线程被调度器用来执行预定的作业.这就是Quartz怎样能并发运行多个作业的原理.Quartz依赖一套松耦合的线程池管理部件来管理线程环境. 2.项目相关 ? 该定时器Demo用于定时执行制定路径下的jar