Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 自定义线程池-在不调用start()的情况下调用runnable_Java_Multithreading - Fatal编程技术网

Java 自定义线程池-在不调用start()的情况下调用runnable

Java 自定义线程池-在不调用start()的情况下调用runnable,java,multithreading,Java,Multithreading,我试图理解自定义线程池的实现,如中所述。轮询出任务队列后,作为 while ((r = taskQueue.poll()) != null) { r.run(); } 代码直接调用run方法,而不首先调用start()。所以,我有点困惑,如果不在runnable上创建线程,然后调用start方法,如何启动runnable?有谁能帮我澄清一下我的困惑,因为我缺乏理解。谢谢 class CustomThreadPool { // holds tasks

我试图理解自定义线程池的实现,如中所述。轮询出任务队列后,作为

while ((r = taskQueue.poll()) != null) {
          r.run();
       }
代码直接调用run方法,而不首先调用
start()
。所以,我有点困惑,如果不在runnable上创建线程,然后调用start方法,如何启动runnable?有谁能帮我澄清一下我的困惑,因为我缺乏理解。谢谢

class CustomThreadPool {
    // holds tasks
    private BlockingQueue<Runnable> runnableQueue;
    // holds the pool of worker threads
    //private List<WorkerThread> threads;
    // check if shutdown is initiated
    private AtomicBoolean isThreadPoolShutDownInitiated;
    public CustomThreadPool(final int noOfThreads) {
        this.runnableQueue = new LinkedBlockingQueue<>();
        //this.threads = new ArrayList<>(noOfThreads);
        this.isThreadPoolShutDownInitiated = new AtomicBoolean(false);
        // create worker threads
        for (int i = 1; i <= noOfThreads; i++) {
            WorkerThread thread = new WorkerThread(runnableQueue, this);
            thread.setName("Worker Thread - " + i);
            thread.start();
           // threads.add(thread);
        }
    }
    public void execute(Runnable r) throws InterruptedException {
        if (!isThreadPoolShutDownInitiated.get()) {
            runnableQueue.put(r);
        } else {
            throw new InterruptedException("Thread Pool shutdown is initiated, unable to execute task");
        }
    }
    public void shutdown() {
        isThreadPoolShutDownInitiated = new AtomicBoolean(true);
    }


    private class WorkerThread extends Thread {
        // holds tasks
        private BlockingQueue<Runnable> taskQueue;
        // check if shutdown is initiated
        private CustomThreadPool threadPool;
        public WorkerThread(BlockingQueue<Runnable> taskQueue, CustomThreadPool threadPool) {
            this.taskQueue = taskQueue;
            this.threadPool = threadPool;
        }
        @Override
        public void run() {
            try {
                // continue until all tasks finished processing
                while (!threadPool.isThreadPoolShutDownInitiated.get() || !taskQueue.isEmpty()) {
                    Runnable r;
                    // Poll a runnable from the queue and execute it
                    while ((r = taskQueue.poll()) != null) {
                        r.run();
                    }
                    Thread.sleep(1);
                }
            } catch (RuntimeException | InterruptedException e) {
                throw new CustomThreadPoolException(e);
            }
        }
    }
    private class CustomThreadPoolException extends RuntimeException {
        private static final long serialVersionUID = 1L;
        public CustomThreadPoolException(Throwable t) {
            super(t);
        }
    }
}

public class ThreadPoolTest {
    public static void main(String[] args) throws InterruptedException {
        Runnable r = () -> {
            try {
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName() + " is executing task.");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        CustomThreadPool threadPool = new CustomThreadPool(2);
        threadPool.execute(r);
        threadPool.execute(r);
        threadPool.shutdown();
        // threadPool.execute(r);
    }
}
class自定义线程池{
//执行任务
私有阻塞队列runnableQueue;
//保存工作线程池
//私有列表线程;
//检查是否启动了关机
私有原子布尔ISThreadPoolShutdowInitiated;
公共自定义线程池(最终int noOfThreads){
this.runnableQueue=new LinkedBlockingQueue();
//this.threads=newarraylist(noOfThreads);
this.isThreadPoolShutDownInitiated=new AtomicBoolean(false);
//创建工作线程
对于(int i=1;i{
试一试{
睡眠(1000);
System.out.println(Thread.currentThread().getName()+“正在执行任务”);
}捕捉(中断异常e){
e、 printStackTrace();
}
};
CustomThreadPool threadPool=新CustomThreadPool(2);
threadPool.execute(r);
threadPool.execute(r);
threadPool.shutdown();
//threadPool.execute(r);
}
}

您的线程池类调用
thread.start()
,它通过调用
thread.run()
调用
runnable.run()
。最后一个方法是为使用runnable初始化的线程设计的,可以直接或通过
start()
调用

根据:
start()
使该线程开始执行;Java虚拟机调用该线程的run方法

编辑

调用
runnable.run()
method只是同步地在当前线程(调用该方法的线程)上执行runnable。在您的情况下,它是单独的线程(在CustomThreadPool中创建)。您可以在
main()中直接调用
run()
,它将在主线程上同步执行runnable。通常,该示例不会打破任何使用runnable的概念,因为它在单独的线程上执行runnable


长话短说:异步行为是通过在不同的线程上执行可运行程序来实现的。在单个线程的范围内,调用多个可运行程序的
run()
将一个接一个地同步执行它们。

实际上,这是添加到队列
threadPool.execute(r)中的不同可运行程序;
在main方法中。
thread.start()
启动工作线程不可运行的线程,该线程已添加到任务中queue@user2269170抱歉误解。正在调用
run()
runnable方法是完全合法的,不需要为其创建单独的线程。但是,它打破了runnable的概念,即它是需要异步执行的任务的特殊接口。但是在您的情况下,这些任务在单独的线程上调用,因为这些线程是初始化的在里面CustomThreadPool@user2269170我编辑了我的答案,它可能不是很清楚,所以让我知道,如果你仍然需要帮助或澄清你的答案和编辑。我明白你的意思,但是让它运行有什么意义?我已经更改了我在本地机器上的代码以执行不可运行的任务,它以同样的行为运行。但是我怀疑是,在什么特殊情况下runnable会有不同?@user2269170在您提供的示例中,runnable用于方便将任务传递给自定义池中的线程。此接口提供了包装void函数或void lambda的功能。