1. 程式人生 > 其它 >一般情況下不存在取消正在執行的定時任務的方法

一般情況下不存在取消正在執行的定時任務的方法

取消正在執行的定時任務的主要需求分為兩種:

1.負責執行的Java執行緒直接終止被殺死

2.定時任務本身的程式碼邏輯中加入了標誌位判斷是否結束。

 

實際業務中,大多數都是第一種,這是基本無法做到的。能取消正在執行的任務,一般都是第二種。

 

1.實際業務中的定時任務一般是這樣:到了固定時間,執行某些SQL將查詢的結果進行某些處理

2.我問問你:已經執行SQL的時候,你有辦法通過java程式碼停止嗎?沒辦法的,所以別想東想西了,我特麼最無語的就是當初做這個需求的時候:專案經理要我實現取消定時任務時,如果任務已經在執行中了,讓正在執行的任務停止。當時我就和他掰扯,這咋實現,不行的啊,頂多是繼續讓任務執行完某個節點準備執行下一個節點的時候進行判斷是否要終止,他讓我上網找個解決方法。……

3.網上所謂的可以停止的方法實現:就是加一個isInterrupted的標誌位判斷,但是實際上,如果你是通過服務呼叫,並且被呼叫方的程式碼無法更改,你實際上是沒有辦法去處理的。

4.服務呼叫另一個方法,該方法不允許修改,並且此方法執行需要半個小時。要求:執行到15分鐘的時候,停止這個方法。結論:做不到。

Quartz的註釋上面就這樣說過:

/* 
 * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
 * use this file except in compliance with the License. You may obtain a copy 
 * of the License at 
 * 
 *   
http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. *
*/ package org.quartz; /** * The interface to be implemented by <code>{@link Job}s</code> that provide a * mechanism for having their execution interrupted. It is NOT a requirement * for jobs to implement this interface - in fact, for most people, none of * their jobs will. * * <p>Interrupting a <code>Job</code> is very analogous in concept and * challenge to normal interruption of a <code>Thread</code> in Java. * * <p> * The means of actually interrupting the Job must be implemented within the * <code>Job</code> itself (the <code>interrupt()</code> method of this * interface is simply a means for the scheduler to inform the <code>Job</code> * that a request has been made for it to be interrupted). The mechanism that * your jobs use to interrupt themselves might vary between implementations. * However the principle idea in any implementation should be to have the * body of the job's <code>execute(..)</code> periodically check some flag to * see if an interruption has been requested, and if the flag is set, somehow * abort the performance of the rest of the job's work. An example of * interrupting a job can be found in the java source for the class * <code>org.quartz.examples.DumbInterruptableJob</code>. It is legal to use * some combination of <code>wait()</code> and <code>notify()</code> * synchronization within <code>interrupt()</code> and <code>execute(..)</code> * in order to have the <code>interrupt()</code> method block until the * <code>execute(..)</code> signals that it has noticed the set flag. * </p> * * <p> * If the Job performs some form of blocking I/O or similar functions, you may * want to consider having the <code>Job.execute(..)</code> method store a * reference to the calling <code>Thread</code> as a member variable. Then the * Implementation of this interfaces <code>interrupt()</code> method can call * <code>interrupt()</code> on that Thread. Before attempting this, make * sure that you fully understand what <code>java.lang.Thread.interrupt()</code> * does and doesn't do. Also make sure that you clear the Job's member * reference to the Thread when the execute(..) method exits (preferably in a * <code>finally</code> block. * </p> * * <p> * See Example 7 (org.quartz.examples.example7.DumbInterruptableJob) for a simple * implementation demonstration. * </p> * @see Job * @see StatefulJob * @see Scheduler#interrupt(JobKey) * @see Scheduler#interrupt(String) * * @author James House */ public interface InterruptableJob extends Job { /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Interface. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /** * <p> * Called by the <code>{@link Scheduler}</code> when a user * interrupts the <code>Job</code>. * </p> * * @throws UnableToInterruptJobException * if there is an exception while interrupting the job. */ void interrupt() throws UnableToInterruptJobException; }

主要內容是說:中斷作業在概念上非常類似於Java中執行緒的正常中斷,並且是一種挑戰。作業用於中斷自身的機制可能因實現而異。然而,任何實現中的原則思想都應該是讓作業的主體執行定期檢查一些標誌,檢視是否請求了中斷,如果設定了該標誌,則以某種方式中止作業其餘工作的執行。並且quartz給了一個expamle,就是通過判斷標誌位實現的。

https://github.com/quartz-scheduler/quartz/tree/master/distribution/examples/src/main/java/org/quartz/examples/example7