gpt4 book ai didi

java - 自定义线程池 - 无需调用 start() 即可调用可运行线程

转载 作者:行者123 更新时间:2023-11-30 05:22:50 24 4
gpt4 key购买 nike

我试图了解自定义线程池实现,如 https://www.roytuts.com/custom-thread-pool-in-java/ 中所述。 。从任务队列中轮询后为

while ((r = taskQueue.poll()) != null) {
r.run();
}

代码直接调用run方法,没有先调用start()。所以,我有点困惑如何启动 runnable 而无需在 runnable 上创建线程然后调用 start 方法?谁能澄清我缺乏理解的困惑。谢谢

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

最佳答案

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

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

编辑

调用runnable.run()方法只是同步在当前线程(在其中调用该方法)上执行runnable。在您的情况下,它是单独的(在 CustomThreadPool 中创建)。您可以在main()中直接调用run(),这将在主线程上同步执行runnable。一般来说,该示例不会破坏使用可运行对象的任何概念,因为它在单独的线程上执行它们。

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

关于java - 自定义线程池 - 无需调用 start() 即可调用可运行线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59243380/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com