[英]Is it safe to reschedule a task before it done when using ScheduledExecutorService?
[英]How to reschedule a task using a ScheduledExecutorService?
我在java docs中看到了這個: ScheduledAtFixedRate ,它說
如果任務的任何執行遇到異常,則后續執行被禁止
我不希望在我的應用程序中發生這種情況。 即使我看到異常,我也總是希望后續執行發生並繼續。 如何從ScheduledExecutorService
獲取此行為。
使用try / catch包圍Callable.call方法或Runnable.run方法...
例如:
public void run()
{
try
{
// ... code
}
catch(final IOException ex)
{
// handle it
}
catch(final RuntimeException ex)
{
// handle it
}
catch(final Exception ex)
{
// handle it
}
catch(final Error ex)
{
// handle it
}
catch(final Throwable ex)
{
// handle it
}
}
請注意,除了編譯器告訴你的內容之外還有其他任何東西(我的示例中的IOException)並不是一個好主意,但有時候,這聽起來像其中之一,如果你正確處理它可以解決它。
請記住,像Error這樣的東西非常糟糕 - 虛擬機內存不足等等......所以要小心你如何處理它們(這就是為什么我將它們分成自己的處理程序而不僅僅是捕獲(最終的Throwable ex)而沒有什么其他)。
從jcabi-log嘗試VerboseRunnable
類,它執行TofuBeer建議的包裝:
import com.jcabi.log.VerboseRunnable;
Runnable runnable = new VerboseRunnable(
Runnable() {
public void run() {
// do business logic, may Exception occurs
}
},
true // it means that all exceptions will be swallowed and logged
);
現在,當任何人調用runnable.run()
不會拋出任何異常。 相反,它們被吞下並記錄(到SLF4J)。
如果您想要的是后續執行,並且即使在異常之后仍然繼續執行 ,則此代碼應該有效。
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Runnable task = new Runnable() {
@Override
public void run() {
try{
System.out.println(new Date() + " printing");
if(true)
throw new RuntimeException();
} catch (Exception exc) {
System.out.println(" WARN...task will continiue"+
"running even after an Exception has araised");
}
}
};
executor.scheduleAtFixedRate(task, 0, 3, TimeUnit.SECONDS);
如果Throwable
比其他的Exception
已經發生,你可能不希望后續執行得到執行。
這是輸出
星期五11月23日12:09:38 JST 2012印刷
_WARN ...即使在異常提出后,任務也將繼續執行
星期五11月23日12:09:41 JST 2012印刷
_WARN ...即使在異常提出后,任務也將繼續執行
星期五11月23日12:09:44 JST 2012印刷
_WARN ...即使在異常提出后,任務也將繼續執行
星期五11月23日12:09:47 JST 2012印刷
_WARN ...即使在異常提出后,任務也將繼續執行
我有同樣的問題。 我也試過run()方法中的try塊但它不起作用。
所以到目前為止我做了一些工作:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
public class Test2 {
static final ExecutorService pool = Executors.newFixedThreadPool(3);
static final R1 r1 = new R1();
static final R2 r2 = new R2();
static final BlockingQueue deadRunnablesQueue = new LinkedBlockingQueue<IdentifiableRunnable>();
static final Runnable supervisor = new Supervisor(pool, deadRunnablesQueue);
public static void main(String[] args) {
pool.submit(r1);
pool.submit(r2);
new Thread(supervisor).start();
}
static void reSubmit(IdentifiableRunnable r) {
System.out.println("given to an error, runnable [" + r.getId()
+ "] will be resubmited");
deadRunnablesQueue.add(r);
}
static interface IdentifiableRunnable extends Runnable {
String getId();
}
static class Supervisor implements Runnable {
private final ExecutorService pool;
private final BlockingQueue<IdentifiableRunnable> deadRunnablesQueue;
Supervisor(final ExecutorService pool,
final BlockingQueue<IdentifiableRunnable> deadRunnablesQueue) {
this.pool = pool;
this.deadRunnablesQueue = deadRunnablesQueue;
}
@Override
public void run() {
while (true) {
IdentifiableRunnable r = null;
System.out.println("");
System.out
.println("Supervisor will wait for a new runnable in order to resubmit it...");
try {
System.out.println();
r = deadRunnablesQueue.take();
} catch (InterruptedException e) {
}
if (r != null) {
System.out.println("Supervisor got runnable [" + r.getId()
+ "] to resubmit ");
pool.submit(r);
}
}
}
}
static class R1 implements IdentifiableRunnable {
private final String id = "R1";
private long l;
@Override
public void run() {
while (true) {
System.out.println("R1 " + (l++));
try {
Thread.currentThread().sleep(5000);
} catch (InterruptedException e) {
System.err.println("R1 InterruptedException:");
}
}
}
public String getId() {
return id;
}
}
static class R2 implements IdentifiableRunnable {
private final String id = "R2";
private long l;
@Override
public void run() {
try {
while (true) {
System.out.println("R2 " + (l++));
try {
Thread.currentThread().sleep(5000);
} catch (InterruptedException e) {
System.err.println("R2 InterruptedException:");
}
if (l == 3) {
throw new RuntimeException(
"R2 error.. Should I continue to process ? ");
}
}
} catch (final Throwable t) {
t.printStackTrace();
Test2.reSubmit(this);
}
}
public String getId() {
return id;
}
}
}
您可以嘗試注釋掉Test2.reSubmit(this)以查看沒有它,R2將停止工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.