org.seasar.extension.timer.TimeoutManager Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2004-2015 the Seasar Foundation and the Others.
*
* 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.seasar.extension.timer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.seasar.framework.util.SLinkedList;
/**
* Timerを扱うクラスです。
*
* @author higa
*
*/
public class TimeoutManager implements Runnable {
/**
* シングルトンのためのインスタンスです。
*/
protected static final TimeoutManager instance = new TimeoutManager();
/**
* Timerのための{@link Thread}です。
*/
protected Thread thread;
/**
* {@link TimeoutTask}管理用のリストです。
*/
protected final SLinkedList timeoutTaskList = new SLinkedList();
private TimeoutManager() {
}
/**
* シングルトン用のインスタンスを返します。
*
* @return シングルトン用のインスタンス
*/
public static TimeoutManager getInstance() {
return instance;
}
/**
* 処理を開始します。
*/
public synchronized void start() {
if (thread == null) {
thread = new Thread(this, "Seasar2-TimeoutManager");
thread.setDaemon(true);
thread.start();
}
}
/**
* 処理を停止します。
*/
public synchronized void stop() {
if (thread != null) {
thread.interrupt();
thread = null;
}
}
/**
* スレッドに割り込みを行い、終了するまで待機します。
*
* @param timeoutMillis
* 待機する時間(ミリ秒単位)
* @return スレッドが終了した場合はtrue
* @throws InterruptedException
* 待機中に割り込まれた場合
*/
public boolean stop(long timeoutMillis) throws InterruptedException {
Thread thread = this.thread;
synchronized (this) {
if (thread == null) {
return true;
}
this.thread = null;
}
thread.interrupt();
thread.join(timeoutMillis);
return !thread.isAlive();
}
/**
* 管理している {@link TimeoutTask}をクリアします。
*/
public synchronized void clear() {
timeoutTaskList.clear();
}
/**
* {@link TimeoutTarget}を追加します。
*
* @param timeoutTarget timeoutTarget
* @param timeout timeout
* @param permanent permanent
* @return {@link TimeoutTask}
*/
public synchronized TimeoutTask addTimeoutTarget(
final TimeoutTarget timeoutTarget, final int timeout,
final boolean permanent) {
final TimeoutTask task = new TimeoutTask(timeoutTarget, timeout,
permanent);
timeoutTaskList.addLast(task);
if (timeoutTaskList.size() == 1) {
start();
}
return task;
}
/**
* 管理している {@link TimeoutTask}の数を返します。
*
* @return 管理している {@link TimeoutTask}の数
*/
public synchronized int getTimeoutTaskCount() {
return timeoutTaskList.size();
}
@Override
public void run() {
boolean interrupted = false;
for (;;) {
final List expiredTask = getExpiredTask();
for (final Iterator it = expiredTask.iterator(); it.hasNext();) {
final TimeoutTask task = it.next();
task.expired();
if (task.isPermanent()) {
task.restart();
}
}
if (interrupted || thread.isInterrupted() || stopIfLeisure()) {
return;
}
try {
Thread.sleep(1000);
} catch (final InterruptedException e) {
interrupted = true;
}
}
}
/**
* 期限の切れた {@link TimeoutTask}のリストを返します。
*
* @return 期限の切れた {@link TimeoutTask}のリスト
*/
protected synchronized List getExpiredTask() {
final List expiredTask = new ArrayList<>();
try {
if (timeoutTaskList == null || timeoutTaskList.isEmpty()) {
return expiredTask;
}
} catch (NullPointerException e) {
return expiredTask;
}
for (SLinkedList.Entry e = timeoutTaskList.getFirstEntry(); e != null; e = e
.getNext()) {
final TimeoutTask task = (TimeoutTask) e.getElement();
if (task.isCanceled()) {
e.remove();
continue;
}
if (task.isStopped()) {
continue;
}
if (task.isExpired()) {
expiredTask.add(task);
if (!task.isPermanent()) {
e.remove();
}
}
}
return expiredTask;
}
/**
* 管理しているタスクが無いなら処理を停止します。
*
* @return 停止したかどうか
*/
protected synchronized boolean stopIfLeisure() {
try {
if (timeoutTaskList == null || timeoutTaskList.isEmpty()) {
thread = null;
return true;
}
} catch (NullPointerException e) {
return true;
}
return false;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy