我有一个 Web 应用程序,它接受来自用户的一些数据来创建任务,然后应该执行该任务。
由于任务的执行是从互联网上下载一些东西,这将花费一些时间,所以我尝试创建一个新的线程来完成这项工作。
这是我的想法:
创建一个
LoaderThread
用来下载数据的。并且LoaderThread
持有一个ArrayList
用于放置的字段Task
。A
Servlet
处理请求和响应。启动时
Servlet
,启动LoaderThread
在 servlet 运行期间,将任务添加到
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
实例?如果是这样,如何避免呢?
看来我可以使用其他实现,但我想知道我的案例是否可以重构?
因为我想学习一些我错过的东西。:) 谢谢。