是否可以通过在run()方法中调用run()来启动一个线程?

ama*_*ish 6 java multithreading

我知道不应该调用run方法来启动一个新的线程执行,但是我在引用这篇文章时他们调用了runnable.run();另一个run方法,它似乎意味着它启动了一个新线程或者它根本没有创建线程,它只是创建一个新线程并在同一个线程中运行所有runnable,即任务任务?

这是文章引用的代码.

 public class ThreadPool {

    private BlockingQueue taskQueue = null;
    private List<PoolThread> threads = new ArrayList<PoolThread>();
    private boolean isStopped = false;

    public ThreadPool(int noOfThreads, int maxNoOfTasks){
        taskQueue = new BlockingQueue(maxNoOfTasks);

        for(int i=0; i<noOfThreads; i++){
            threads.add(new PoolThread(taskQueue));
        }
        for(PoolThread thread : threads){
            thread.start();
        }
    }

    public synchronized void  execute(Runnable task) throws Exception{
        if(this.isStopped) throw
            new IllegalStateException("ThreadPool is stopped");

        this.taskQueue.enqueue(task);
    }

    public synchronized void stop(){
        this.isStopped = true;
        for(PoolThread thread : threads){
           thread.doStop();
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

和

public class PoolThread extends Thread {

    private BlockingQueue taskQueue = null;
    private boolean       isStopped = false;

    public PoolThread(BlockingQueue queue){
        taskQueue = queue;
    }

    public void run(){
        while(!isStopped()){
            try{
                Runnable runnable = (Runnable) taskQueue.dequeue();
                runnable.run();
            } catch(Exception e){
                //log or otherwise report exception,
                //but keep pool thread alive.
            }
        }
    }

    public synchronized void doStop(){
        isStopped = true;
        this.interrupt(); //break pool thread out of dequeue() call.
    }

    public synchronized boolean isStopped(){
        return isStopped;
    }
}
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 为什么要thread.start(); 在构造函数中调用?

  2. 如果thread.start();我如何识别我的任务 甚至在调用this.taskQueue.enqueue(task)之前调用 ;

  3. 要了解所有这些,请为此示例发布一个驱动程序类,其中包含maxNoOfTasks = 10和noOfThreads = 3.并且对于相同的输出将非常感激.

  4. Runnable.run()里面的run方法是否启动了一个新线程?

谢谢

T.J*_*der 10

我在他们所说的那篇文章中引用了这篇文章runnable.run(); 在另一个run方法中,它似乎意味着它启动了一个新线程.

看一下代码,我根本没有看到这个含义.

它没有开始新的线程.它正在Runnable当前池线程上的队列中运行下一个.

我知道不应该调用run方法来启动新的线程执行...

不应该,不可以.:-) 在当前线程上调用run只是调用run,就像任何其他方法调用一样.

  1. 为什么thread.start();在内部构造函数中调用?

启动刚刚创建的线程new PoolThread(taskQueue).

  1. 如果thread.start();在调用之前调用,我如何识别我的任务this.taskQueue.enqueue(task);

你把它传递给了execute.它被添加到要做的事情的队列中(taskQueue).其中的PoolThread,且s ThreadPool创建将它捡起来时,它的下一个免费的.

  1. 要理解所有这些,请为此示例发布一个驱动程序类,其中maxNoOfTasks = 10和noOfThreads = 3.并且非常感谢输出.

我不知道司机班的意思,但我认为回答问题就足够了.

  1. Runnable.run()内部运行方法是否启动一个新线程?

没有.


因此,要了解这是做什么的,请说创建一个ThreadPool包含5个线程.该ThreadPool构造函数创建和五个开始PoolThread立即线程.那些线程经常检查taskQueue是否有任何事情要做,如果有的话,他们会这样做.

当然,最初taskQueue总是空的,所以线程忙着等待,不断地旋转检查某些东西taskQueue.(这不是很理想,它没有任何理由燃烧CPU.最好在没有任何事情时暂停线程,但这开始与实际问题相差甚远.)

然后,在某些时候,您调用execute并传递任务.这增加了它taskQueue.下一次五个线程中的一个检查输入内容时taskQueue,它会找到它,并在该线程上运行它(而不是新线程).