代码之家  ›  专栏  ›  技术社区  ›  Cratylus

通过执行器的Java线程重用

  •  5
  • Cratylus  · 技术社区  · 14 年前

    我对以下问题感到困惑:
    要在Java程序中使用线程,最简单的方法是扩展线程类并实现可运行接口(或者简单地实现可运行的接口)。
    启动线程的执行。我们必须调用线程的方法start(),该方法反过来调用线程的方法run()。所以这条线就开始了。
    方法start()(除非我错了) 必须准确且仅调用一次 对于每个线程。因此,线程实例不能被重用,除非运行方法本身以某种方式在无限循环中运行,这有助于自定义实现线程的重用。
    现在JavaDoc link text

    调用execute将重用以前构造的线程(如果可用)

    我不明白这是如何实现的。 我在Executor方法的Execute方法中提供了我的自定义线程,例如

      ExecutorService myCachedPool = Executors.newCachedThreadPool();
      myCachedPool.execute(new Runnable(){public void run(){  
         //do something time consuming
    
      }});
    

    如何重用我删除到执行器框架的这个自定义线程?
    执行器是否允许调用方法start()超过1次,而我们不能在程序中调用? 我误解了什么吗?

    谢谢您。

    3 回复  |  直到 14 年前
        1
  •  4
  •   Jon Skeet    14 年前

    注意这不是 Executor 那个电话 start() -它是 ExecutorService 。不,不打电话 开始() 两次。它不会启动您直接使用的任务 Thread.start() …相反,它启动一个了解线程池工作队列的线程。线程将基本上等待,直到有一些工作要做,然后拿起它并执行它,然后再返回到等待状态。因此,尽管线程执行多个任务, thread.start()。 只调用一次。

    编辑:从评论来看,你对 Runnable (这是要执行的任务)和 Thread (这就是执行任务的原因)。

    同一线程可以执行多个任务。对于不使用线程池的非常简单的示例,请考虑以下内容:

    public class MultiRunnable implements Runnable
    {
        private final List<Runnable> runnables;
    
        public MultiRunnable(List<Runnable> runnables)
        {
            this.runnables = runnables;
        }
    
        public void run()
        {
            for (Runnable runnable : runnables)
            {
                 runnable.run();
            }
        }
    }
    

    (忽略使用 List<T> 来自多个线程。)

    你可以创造一大堆 可运行 任务可以做不同的事情,然后创建一个 MultiRunnable 依次运行它们。传递的实例 多运行 进入 螺纹 构造函数,然后当您启动线程时,它将执行每个原始的可运行任务。有帮助吗?

        2
  •  5
  •   jbindel    14 年前

    它不会多次调用start();相反,池中的线程永远不会完成,只是保持活动状态---等待。如果您想查看源代码,可以下载它。

    线程池中的每个线程 wait() 让执行器给它一个新的可运行文件,但线程是自己的 run() 方法尚未完成。它只是等待一个新的可运行文件被提供给执行器。

        3
  •  1
  •   Leo Izen    14 年前

    要多次“启动”线程,请创建一个可运行的。例如:

    //NO
    private class T extends Thread { //not necessary to implement runnable
        public void run(){
            //...
        }
    }
    void someMethod(){
        T a = new T();
        a.start();
        a.start(); //NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO
    }
    

    相反,

    //Yes
    private class T implements Runnable {
        public void run(){
            //...
        }
    }
    void someMethod(){
        T a = new T();
        new Thread(a).start();
        new Thread(a).start(); //YES YES YES
    }
    

    也可以这样做:

    void someMethod(){
        final Runnable r = new Runnable(){
            public void run(){
                //...
            }
        };
        new Thread(r).start();
        new Thread(r).start();
    }
    // r could also be a field of you class.