ThreadPoolExecutor 中的同步队列
SynchronousQueue in ThreadPoolExecutor
我正在尝试了解 ThreadPoolExecutor
中队列的行为。在下面的程序中,当我使用 LinkedBlockingQueue
时,我一次只能向线程池提交一个任务。但是,如果我将 LinkedBlockingQueue
替换为 SynchronousQueue
,我可以立即将所有 5 个任务提交到池中。在这种情况下,SynchronousQueue
与 LinkedBlockingQueue
有何不同?
Java 程序:
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Sample {
public static void main(String[] args) throws InterruptedException {
LinkedBlockingQueue<Runnable> threadPoolQueue = new LinkedBlockingQueue<>();
// SynchronousQueue<Runnable> threadPoolQueue = new SynchronousQueue<>();
ThreadFactory threadFactory = Executors.defaultThreadFactory();
ThreadPoolExecutor tpe = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, threadPoolQueue, threadFactory);
Runnable np;
for (int i = 1; i <= 5; i++) {
np = new SampleWorker("ThreadPoolWorker " + i);
tpe.submit(np);
}
System.out.println(tpe.getCorePoolSize());
System.out.println(tpe.getPoolSize());
System.out.println(tpe.getActiveCount());
tpe.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
tpe.shutdown();
System.out.println("Main task finished");
}
}
class SampleWorker implements Runnable {
private String workerName;
SampleWorker(String tName) {
workerName = tName;
}
@Override
public void run() {
try {
for (int i = 1; i <= 10; i++) {
Thread.sleep(3000);
System.out.println(this.workerName);
}
System.out.println(this.workerName + " finished");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
当您向 ThreadPoolExecutor
提交任务时,它的工作方式如下:
if (numberOfWorkingThreads < corePoolSize) {
startNewThreadAndRunTask();
} else if (workQueue.offer(task)) {
if (numberOfWorkingThreads == 0) {
startNewThreadAndRunTask();
}
} else if (numberOfWorkingThreads < maxPoolSize)
startNewThreadAndRunTask();
} else {
rejectTask();
}
- 当使用没有初始值的
LinkedBlockingQueue
时,
workQueue.offer(task)
总会成功,结果只有一个
线程已启动。
- 调用
SynchronousQueue.offer(task)
时,只有在
另一个线程正在等待接收它。因为没有等待
thread, false
将被返回并创建新线程
时间。
我正在尝试了解 ThreadPoolExecutor
中队列的行为。在下面的程序中,当我使用 LinkedBlockingQueue
时,我一次只能向线程池提交一个任务。但是,如果我将 LinkedBlockingQueue
替换为 SynchronousQueue
,我可以立即将所有 5 个任务提交到池中。在这种情况下,SynchronousQueue
与 LinkedBlockingQueue
有何不同?
Java 程序:
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Sample {
public static void main(String[] args) throws InterruptedException {
LinkedBlockingQueue<Runnable> threadPoolQueue = new LinkedBlockingQueue<>();
// SynchronousQueue<Runnable> threadPoolQueue = new SynchronousQueue<>();
ThreadFactory threadFactory = Executors.defaultThreadFactory();
ThreadPoolExecutor tpe = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, threadPoolQueue, threadFactory);
Runnable np;
for (int i = 1; i <= 5; i++) {
np = new SampleWorker("ThreadPoolWorker " + i);
tpe.submit(np);
}
System.out.println(tpe.getCorePoolSize());
System.out.println(tpe.getPoolSize());
System.out.println(tpe.getActiveCount());
tpe.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
tpe.shutdown();
System.out.println("Main task finished");
}
}
class SampleWorker implements Runnable {
private String workerName;
SampleWorker(String tName) {
workerName = tName;
}
@Override
public void run() {
try {
for (int i = 1; i <= 10; i++) {
Thread.sleep(3000);
System.out.println(this.workerName);
}
System.out.println(this.workerName + " finished");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
当您向 ThreadPoolExecutor
提交任务时,它的工作方式如下:
if (numberOfWorkingThreads < corePoolSize) {
startNewThreadAndRunTask();
} else if (workQueue.offer(task)) {
if (numberOfWorkingThreads == 0) {
startNewThreadAndRunTask();
}
} else if (numberOfWorkingThreads < maxPoolSize)
startNewThreadAndRunTask();
} else {
rejectTask();
}
- 当使用没有初始值的
LinkedBlockingQueue
时,workQueue.offer(task)
总会成功,结果只有一个 线程已启动。 - 调用
SynchronousQueue.offer(task)
时,只有在 另一个线程正在等待接收它。因为没有等待 thread,false
将被返回并创建新线程 时间。