外部イベントをリッスンするオブジェクトがあります。イベントを受け取ると、オブジェクトはタスク ( Runnable ) を実行する必要があります。ただし、次の制限があります。
タスクの実行が開始されたら、元のタスクが終了してから一定の時間が経過するまで (スロットリング)、他のタスクを開始しないでください (無視できます)。
セマフォを使用した推奨実装は次のとおりです。
public class Sample {
private final Semaphore semaphore = new Semaphore(1);
private final ScheduledExecutorService executor;
public Sample(ScheduledExecutorService executor) {
this.executor = executor;
}
public void tryRun() {
if (semaphore.tryAcquire()) {
try {
executor.submit(
new Runnable() {
@Override
public void run() {
try {
doIt();
} finally {
try {
executor.schedule(
new Runnable() {
@Override
public void run() {
semaphore.release();
}
},
1,
TimeUnit.MINUTES
);
} catch (Throwable t) {
semaphore.release();
}
}
}
}
);
} catch (Throwable t) {
semaphore.release();
}
}
}
private void doIt() {
// the exact task executing logic is here
}
}
コードは私には冗長すぎるようです。これを行うより良い方法はありますか?
PSもう1つの制限は、ScheduledExecutorServiceが外部エグゼキューターへの唯一のインターフェースであり、オブジェクト内で独自のスレッド/エグゼキューターを開始できないことです