ユーザーからデータを受け取ってタスクを作成する Web アプリケーションがあり、タスクを実行する必要があります。
タスクの実行はインターネットから何かをダウンロードすることなので、時間がかかります。そのため、仕事をするために新しいスレッドを作成しようとしました。
これは私の考えです:
LoaderThread
データをダウンロードするために使用されるを作成します。そして、プットのためLoaderThread
に使用されるホールドフィールド。ArrayList
Task
Servlet
リクエストとレスポンスを処理するための A。Servlet
起動したら、LoaderThread
サーブレットの実行中に、タスクを
LoaderThread
.
これはコードです(一部は省略されています):
public class RwdServlet extends HttpServlet {
private StaticMapLoader loader;
@Override
public void init() throws ServletException {
super.init();
loader = new StaticMapLoader();
loader.startRunning();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Task t=createTask(req);
loader.addTask(t);
}
@Override
public void destroy() {
loader.stopRunning();
}
}
public class StaticMapLoader extends Thread {
private List<Task> tasks = new ArrayList<Task>();
private boolean running = false;
@Override
public void run() {
while (running) {
if (tasks.size() > 0) {
Task t = tasks.get(0);
log.info(t);
if (t != null && t.status == Status.waiting) {
tasks.remove(0);
t.status = Status.running;
downLoad(t);
}
}
}
}
private void downLoad(Task t) {
//download file
}
public void addTask(Task t) {
tasks.add(t);
}
public void startRunning() {
running = true;
this.start();
}
public void stopRunning() {
running = false;
this.interrupt();
}
}
tasks
上記のコードは機能しましたが、空で新しくtask
追加されていない場合でも、ループが実行され続けることがわかりました。
LoaderThread
そこで、タスクがないときにサスペンドし、新しいタスクが出てきたときに通知できるようにできればと思います。
だから私はこれを試しました:
@Override
public void run() {
while (running) {
if (tasks.size() > 0) {
Task t = tasks.get(0);
log.info(t);
if (t != null && t.status == Status.waiting) {
tasks.remove(0);
t.status = Status.running;
downLoad(t);
}
} else {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
が空のwait()
場合に を呼び出そうとしました。tasks
しかし、私はそれを目覚めさせる方法がわかりませんか?
また、アプリケーションを改善するために知っておくべきことはありますか?
BWT、複数のLoaderThread
インスタンスが作成される可能性はありますか? もしそうなら、それを避ける方法は?
他の実装も使えそうですが、私のケースはリファクタリングできるのかな?
見逃したことを学びたいので。:) ありがとう。