【问题标题】:making processRequest wait to another thread to end使 processRequest 等待另一个线程结束
【发布时间】:2013-05-08 09:35:07
【问题描述】:

我正在为以下代码寻找更好的解决方案, 我有一个 servlet,当用户按下一个按钮时,它必须处理一个请求, 在做任何事情之前,我希望我的函数等待另一个线程结束他正在做的事情, 现在我正在使用一个简单的会话来做这件事:

boolean converted = (Boolean) request.getSession().getAttribute("converterthread");
        while(!converted){ // Wait
            converted = (Boolean) request.getSession().getAttribute("converterthread");
            }

当线程结束他的工作时,它会将会话的converterthread 属性设置为true。 这一切都很好,但恐怕这不是最好的解决方案,每次都要求会话对服务器的性能不利吗? 我正在尝试使用 this.wait(1000) 使我的函数检查线程是否每秒都结束,但我只是得到一个监视器未找到异常(或类似)。

编辑:在不同的请求方法中(在上一个方法之前调用)我正在创建一个使用 xuggler 类进行转换的线程(这样用户就不会等待所有转换完成结束)。 基本上我创建了一个新的 MyThread(Runnable 的扩展),然后我将会话的“converterthread”属性设置为 false

MyThread r = new MyThread(uploadedFile, fileDir, request.getSession());
request.getSession().setAttribute("converterthread", false);

过了一会儿,我用 MyThread 创建了一个线程并启动它。 这是 MyThread 的样子:

   public class MyThread implements Runnable {

        File uploadedFile;
        File fileDir;
        HttpSession session;
        boolean hasEnded = false;

        public MyThread(File f, File d, HttpSession s) {
            fileDir = d;
            uploadedFile = f;
            session = s;
        }

        public File returnFileDir()
        {
            return fileDir;
        }

        @Override
        public void run() {
            new Converter(uploadedFile.getAbsolutePath(), fileDir.getPath() + "\\video").run();
            //subito dopo voglio eliminare il file precedente
            uploadedFile.delete();  // è sicuro che termina per ultima la conversione
            //Aggiorno lo stato della sessione, sblocca il CutSave se aspettava la conversione
            session.setAttribute("converterthread", true);
            hasEnded = true;
            MyThreadQueue.get().removeThread(this);
            MyThreadQueue.get().runNextThread(); // se c'è un altro thread in attesa allora lo esegue
            //Il meccanismo garantisce un esecuzione dei thread in fila
        }
    }

如您所见,转换后我调用 session.setAttribute("converterthread", true);

【问题讨论】:

  • “我想要另一个线程结束”是什么意思?你想做什么?
  • 线程正在转换文件视频,这需要很长时间,我想在做任何事情之前等待视频的转换(在我的另一个线程中完成),我已经完成了,我只是询问使用 request.getSession().getAttrubute("something") 检查转换状态是否是一件好事
  • 不,这是不对的。如果你能告诉我你是如何处理文件视频的,我可以建议一个简单的方法。当您的应用由容器管理时,您不需要执行多线程。
  • 我已经编辑了这个问题,我使用多线程只是为了让用户更快,因为我上传了一个视频文件并开始在请求方法中进行全部转换
  • 查看答案。

标签: multithreading jsp servlets wait


【解决方案1】:

您可以使用 CountDownLatch,首先在会话中放置一个 countDownLatch

session.setAttribute("latch",new CountDownLatch(1));

工作完成后,打电话

CountDownLatch latch=(CountDownLatch)session.getAttribute("latch");
latch.countDown();

然后将while循环替换为:

CountDownLatch latch=(CoundDownLatch)session.getAttribute("latch");
latch.await(); // will wait for MyThread to call latch.countDown()
//also you can specify a timeout
//latch.await(2000) wait for 2 seconds

更新:

最好不要把session传给另一个线程,直接把countDownLatch传给MyThread实例

【讨论】:

  • session 是 MyThread 的构造函数参数:) 当然最好将 countDownLatch 传递给该线程而不是 HttpSession
  • 是的,刚刚注意到。这就是为什么删除评论。无论如何,在处理容器管理的组件时,这不是正确的方法。看看我的回答。
【解决方案2】:

1) 您不应让 servlet 等待并依赖于忙于做其他事情的线程。这是不对的。

2)如果你真的想分解你的多个任务,那么有一个简单的方法如下:

>> 在您的 jsp/html 页面中,创建 2 个frames

>> 在其中 1 帧中,保留用户按下的按钮,该按钮调用 servlet。在第二帧中,保留视频处理 servlet 或任何你想要的。

>> 当用户按下按钮时,按钮会通过javascript/ajax调用servlet。因此,一旦 servlet 完成其请求,它会将响应发送回框架并将响应附加到框架。在第二帧中,更新将以同样的方式发生。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 2012-07-13
    • 1970-01-01
    • 2021-11-03
    • 2011-07-10
    • 2013-02-03
    • 1970-01-01
    相关资源
    最近更新 更多