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的功能。