6

我对以下内容感到困惑:
要在Java程序中使用线程,最简单的方法是扩展Thread类并实现runnable接口(或简单地实现runnable)。
开始线程的执行。我们必须调用线程的方法start(),然后调用线程的方法run()。于是线程开始了。
start() 方法(除非我错了)必须准确地调用,并且每个线程只调用一次。因此,线程实例不能被重用,除非 run 方法本身以某种方式运行在一些无限循环中,这有助于线程重用的自定义实现。
现在javadoc 链接文本

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

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

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

  }});

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

谢谢你。

4

3 回答 3

5

请注意,这不是Executor调用start()- 它是ExecutorService. 不,它不会调用start()两次。它不会启动您直接使用Thread.start()... 给它的任务,而是启动一个线程,该线程知道该线程池的工作队列。线程基本上会等到有一些工作要做,然后拿起它并执行它,然后再回到等待状态。所以虽然线程执行了几个任务,但Thread.start()只被调用一次。

编辑:从评论来看,您对 a Runnable(要执行的任务)和 a 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>来自多个线程的潜在线程安全问题。)

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

于 2010-09-19T11:23:44.267 回答
5

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

线程池中的每个 Thread 都可以简单wait()的让 Executor 交给它一个新的 Runnable,但是 Thread 自己的run()方法还没有完成。它只是等待一个新的 Runnable 被提供给 Executor。

于 2010-09-19T11:24:31.097 回答
1

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

//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. 
于 2010-09-19T13:44:44.180 回答