【问题标题】:Using sleep() and interrupt() to reuse thread使用 sleep() 和 interrupt() 重用线程
【发布时间】:2011-05-28 09:07:43
【问题描述】:

在一个摇摆应用程序中,我想重新利用一个衍生线程而不是创建一个新线程来服务请求。这是因为请求会在很短的时间间隔内到来,并且为每个请求创建新线程的成本可能很高。

我正在考虑使用 interrupt() 和 sleep() 方法来执行此操作,如下所示,并想知道代码的任何潜在性能问题:

public class MyUtils {
    private static TabSwitcherThread tabSwitcherThread = null;

    public static void handleStateChange(){
        if(tabSwitcherThread == null || !tabSwitcherThread.isAlive()){
            tabSwitcherThread = new TabSwitcherThread();
            tabSwitcherThread.start();
        }
        else
            tabSwitcherThread.interrupt();      
    }

    private static class TabSwitcherThread extends Thread{
        @Override
        public void run() {
           try {
                 //Serve request code

                 //Processing complete, sleep till next request is received (will be interrupted)
                 Thread.sleep(60000);
           } catch (InterruptedException e) {
                //Interrupted execute request
                run();
           }

           //No request received till sleep completed so let the thread die         
        }
   }
}

谢谢

【问题讨论】:

  • 实际上,我认为你是 TabSwitcherThread 迟早会得到 stackoverflow 异常,因为你的 run() 方法中有递归调用:)

标签: java multithreading swing


【解决方案1】:

我不会使用 sleep()interrupt() - 如果我绝对必须使用,我会使用 wait()notify()

但是,是否真的需要这样做而不是使用可以为您处理线程重用的ThreadPoolExecutor?或者也许以生产者/消费者的方式使用BlockingQueue

Java 已经为此提供了足够多的更高级别的构建块,因此您不需要自己深入到这个级别。

【讨论】:

  • 感谢您的回复。这是一个小型 Java 应用程序,我不希望汇集“n”个线程来处理请求。基本上,一次会有一个请求进来。情况就像在文本区域中用户输入了一些东西,这需要处理。我不能在同一个线程中执行此操作,因为它会导致 UI 冻结,因此需要单独的线程。为此,我希望有一个专用线程并避免创建新线程,因为我在创建新线程时经历了相当大的延迟。谢谢!
  • @skk 1 个线程池有什么问题? :)。我已经用如何利用 Java 并发框架的示例代码修改了我的答案。我借用了你的部分代码,希望你不会介意。
  • @skk:一个生产者/消费者队列会为你做这件事,或者一个有一个线程的ThreadPoolExecutor
  • Jon 和 Alvin,查看了 API,是的,带有一个线程的 ThreadPoolExecutor 符合我的需求。非常感谢!
  • @JonSkeet,选择等待/通知而不是睡眠/中断的原因是什么?虽然wait() 确实不需要特定的超时时间,但我们有sleep(long millis),它的最大值约为3 亿年,基本上就像wait()。事实上,我认为睡眠/中断性能更高,因为它不需要进行冗余同步(它只是直接完成工作)。我很想知道你对这个问题的看法。
【解决方案2】:

我认为您正在寻找的是一个线程池。 Java 5 及更高版本带有ThreadPoolExecutor。我建议您使用 Java 提供的内容,而不是自己编写,这样可以节省大量时间和精力。

当然,如果您绝对必须按照您描述的方式进行操作(嘿,有时业务需求让我们的生活变得艰难),那么请按照 Jon 的建议使用 wait() 和 notify()。在这种情况下我不会使用 sleep() ,因为您必须指定超时时间,而且您永远不知道下一个请求何时到来。让一个线程不断唤醒然后重新进入睡眠状态对我来说似乎有点浪费 CPU 周期.

这是一个关于 ThreadPoolExecutor 的nice tutorial

编辑:

下面是一些代码示例:

public class MyUtils {
    private static UIUpdater worker = null;
    private static ExecutorService exeSrv = Executors.newFixedThreadPool(1);

    public static void handleStateChange(){
        if(tabSwitcherThread == null || !tabSwitcherThread.isAlive()){
            worker = new UIUpdater();
        }     

        //this call does not block 
        exeSrv.submit(worker, new Object());     
    }

    private static class UIUpdater implements Runnable{
        @Override
        public void run() {

           //do server request and update ui.
        }
   }
}

【讨论】:

    猜你喜欢
    • 2012-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-31
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    • 2014-03-02
    相关资源
    最近更新 更多