简体   繁体   English

通过执行程序的java线程重用

[英]java thread reusage via executor

I am confused on the following: 我对以下内容感到困惑:
To use threads in a Java program, the simplest way is to extend Thread class and implement the runnable interface (or simply implement runnable). 要在Java程序中使用线程,最简单的方法是扩展Thread类并实现runnable接口(或简单地实现runnable)。
To start the thread's execution. 启动线程的执行。 we must call the Thread's method start(), which in turn calls method run() of the thread. 我们必须调用Thread的方法start(),然后调用线程的方法run()。 And so the thread starts. 所以线程开始了。
The method start() (unless I am wrong) must be called exactly and only once for each thread. 方法start()(除非我错了) 必须完全调用 ,每个线程只调用一次 As a result, thread instances can not be reused unless somehow the run method itself runs in some-short of infinite loop that facilitates a custom implementation of the thread's reusage. 因此,线程实例不能被重用,除非某种方式运行方法本身在某个短的无限循环中运行,这有利于自定义实现线程的重用。
Now the javadoc link text says 现在javadoc 链接文本

Calls to execute will reuse previously constructed threads if available 如果可用,执行调用将重用先前构造的线程

I do not understand how this is implemented. 我不明白这是如何实现的。 I provide in the execute method of the executor method my custom thread eg 我在执行方法的execute方法中提供了我的自定义线程,例如

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

  }});

How can this custom thread I delegeate to the executor framework be reused? 如何重用我删除到执行程序框架的自定义线程?
Is Executor is allowed to call method start() more than 1 time, while we can not in our programs? Executor是否允许调用方法start()超过1次,而我们不能在我们的程序中? Am I misunderstanding something? 我误会了什么吗?

Thank you. 谢谢。

It is not calling start() more than once; 它不是多次调用start(); instead the Thread in the pool never completes, but just stays alive---waiting. 相反,池中的线程永远不会完成,但只是保持活着---等待。 The source code is available for download if you want to look at it. 如果您想查看源代码,可以下载源代码。

Each Thread in the thread pool can simply wait() for the Executor to hand it a new Runnable, but the Thread's own run() method has not completed. 线程池中的每个线程可以简单地wait()执行器将新的Runnable交给它,但Thread自己的run()方法还没有完成。 It simply waits for a new Runnable to be given to the Executor. 它只是等待一个新的Runnable被提供给Executor。

Note that it's not Executor that calls start() - it's ExecutorService . 请注意,调用start()不是Executor - 它是ExecutorService And no, it's not calling start() twice. 不,它不是两次调用start() It doesn't start the task that you give it directly using Thread.start() ... instead, it starts a thread which knows about that thread pool's queue of work. 它不会启动您使用Thread.start()直接提供的任务...而是启动一个知道该线程池的工作队列的线程。 The thread will basically wait until there's some work to do, then pick it up and execute it, before going back to waiting. 线程基本上会等到有一些工作要做,然后拿起并执行它,然后再回到等待状态。 So although the thread performs several tasks, Thread.start() is only called once. 因此,虽然线程执行多个任务,但Thread.start()只被调用一次。

EDIT: Judging by the comments, you're a bit confused about the difference between a Runnable (which is a task to be executed) and a Thread (which is what executes tasks). 编辑:根据评论判断,你对Runnable (这是一个要执行的任务)和一个Thread (执行任务)之间的区别感到有点困惑。

The same thread can execute multiple tasks. 同一个线程可以执行多个任务。 For a very simple example not using a thread pool, consider this: 对于不使用线程池的非常简单的示例,请考虑以下事项:

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();
        }
    }
}

(Ignore the potential thread safety issues of using a List<T> from multiple threads.) (忽略从多个线程使用List<T>的潜在线程安全问题。)

You could create a whole bunch of Runnable tasks capable of doing different things, then create a single MultiRunnable to run them in turn. 您可以创建一大堆能够执行不同操作的Runnable任务,然后创建一个MultiRunnable来依次运行它们。 Pass that instance of MultiRunnable into the Thread constructor, and then when you start the thread, it will execute each of the original runnable tasks. MultiRunnable实例传递给Thread构造函数,然后在启动线程时,它将执行每个原始的可运行任务。 Does that help? 这有帮助吗?

To "start" a thread more than once, create a runnable. 要多次“启动”一个线程,请创建一个runnable。 For example: 例如:

//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
}

Instead, 代替,

//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
}

It is also possible to do this: 也可以这样做:

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. 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM