在线程池执行器类中,有一个maxPoolsize来指定最大线程池大小。这意味着如果线程数少于该数,则应立即执行池中的线程。但我发现并非如此。它实际上不能超越corePoolsize。我很困惑。如果maxPoolsize什么都不做,它的目的是什么?这是我的测试程序:
我已指定corePoolSize=2;maxPoolSize=6;我已经创建了5个线程(可运行)。我认为所有5个线程(可运行)应该同时运行。但事实并非如此。其中只有两个在运行,另外三个被搁置一旁,直到前两个死亡。
我读过很多关于这个话题的帖子。但是没有人能指导我使5个线程同时运行。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class MyThreadPoolExecutorTest2
{
private List<MyRunnable> myRunnables = new ArrayList<>();
public static void main(String[] args)
{
new MyThreadPoolExecutorTest2().test();
}
public void test()
{
int poolSize = 2;
int maxPoolSize = 6;
int threadPoolKeepAliveTimeInSec = 30;
ExecutorService threadPoolExecutor =
new MySimpleThreadPoolExecutor(poolSize, maxPoolSize, threadPoolKeepAliveTimeInSec);
int numOfThread = 5;
System.out.println("Start thread pool test with corePoolSize=" + poolSize + ", maxPoolSize=" + maxPoolSize
+ ", actualThreads=" + numOfThread);
for (int i = 0; i < numOfThread; i++)
{
MyRunnable tempRunnable = new MyRunnable(i + 1, "PoolTest" + (i + 1));
myRunnables.add(tempRunnable);
threadPoolExecutor.execute(tempRunnable);
}
System.out.println("********* wait for a while");
try
{
Thread.sleep(20000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("^^^^^^^^^^ shutdown them all");
for (MyRunnable runnable : myRunnables)
{
runnable.shutdown();
}
System.out.println("Ended thread pool test.");
}
public class MyRunnable implements Runnable
{
private int id = 0;
private String name = "";
private boolean shutdown = false;
public MyRunnable(int id, String name)
{
this.id = id;
this.name = name;
}
@Override
public void run()
{
System.out.println("++++ Starting Thread: " + id + ":" + name);
while (!shutdown)
{
try
{
Thread.sleep(200);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
System.out.println("---- Ended Thread: " + id + ":" + name);
}
public void shutdown()
{
shutdown = true;
}
}
}
class MySimpleThreadPoolExecutor extends ThreadPoolExecutor
{
private static int peakActiveThreads = 0;
private String taskInfo = "";
public MySimpleThreadPoolExecutor(int nThreads, int maxThreads, int threadPoolKeepAliveTimeInSec)
{
super(nThreads, maxThreads, threadPoolKeepAliveTimeInSec * 1000L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
System.out.println("MySimpleThreadPoolExecutor::MySimpleThreadPoolExecutor(), threadPoolSize=" + nThreads
+ ", maxThreadCount=" + maxThreads + ", threadPoolKeepAliveTimeInSec=" + threadPoolKeepAliveTimeInSec);
}
@Override
public void beforeExecute(Thread t, Runnable r)
{
int activeCount = getActiveCount();
if (MySimpleThreadPoolExecutor.peakActiveThreads < activeCount)
{
MySimpleThreadPoolExecutor.peakActiveThreads = activeCount;
}
taskInfo = r.toString();
String msg =
"BeforeE thread(name:id)::" + t.getName() + ":" + t.getId() + ", task::" + r.toString() + "\n"
+ threadPoolInfoStr();
System.out.println("ThreadInfo before, MySimpleThreadPoolExecutor::beforeExecute(), " + msg);
super.beforeExecute(t, r);
}
@Override
public void execute(Runnable command)
{
beforeExecute(Thread.currentThread(), command);
super.execute(command);
}
public String threadPoolInfoStr()
{
return String.format("Thead: %s/%d\n[PoolSize/CorePoolSize] [%d/%d]\nActive: %d\nCompleted: %d\nTask: %d"
+ "\nisShutdown: %s\nisTerminated: %s\npeakActiveThreads: %d\nTaskInfo: %s\nQueueSize: %d", Thread
.currentThread().getName(), Thread.currentThread().getId(), getPoolSize(), getCorePoolSize(),
getActiveCount(), getCompletedTaskCount(), getTaskCount(), isShutdown(), isTerminated(),
MySimpleThreadPoolExecutor.peakActiveThreads, taskInfo, getQueue().size());
}
}
仅当队列已满时,才会添加更多线程。
由于您的LinkedBlockingQueue
没有边界,因此它永远不会满。因此,池中线程的大小永远不会超过核心池大小。
使用TransferQueue
或使用有界队列来解决此问题。
只有当队列已满时,才会创建最大为maxPoolsize的新线程。之前,限制是在corePoolsize定义的限制。
参考:http://www.bigsoft.co.uk/blog/index.php/2009/11/27/rules-of-a-threadpoolexecutor-pool-size
因此,我使用javafx创建了这个应用程序,它有一个登录屏幕,但我在这方面没有任何成功,我已经在这个项目的这个小部分工作了一些天,它根本不能以任何方式工作。我尝试这样做,我看了一些教程,其中大部分都是像下面的代码一样,但它对我来说不起作用,如果有人能帮我解释为什么我的标签文本没有改变(这就是我如何测试登录是否成功),这将是很好的,下面是代码: 控制器: FXML格式
我有一个应用程序,允许用户批量向图像添加水印。该应用程序将只使用一个线程,并且一次只能添加一个水印。 我希望用户能够更改一次运行的水印任务[线程]的数量:可能在设置中为[1-5],并且我不能使用固定的ThreadPool,因为它具有固定的池大小。 我研究了如何使用线程池执行器(ThreadPoolExecutor)私有静态线程池执行器(ThreadPoolExecutor)=(ThreadPool
这是我的第一个JMH基准测试。我可能做错了一切,但是... 我的基准看起来是这样的 是我开始的...等了又等,然后杀了它。我怀疑在< code>@Setup中有问题,所以我简化了它,但是什么都没有改变。这场赛跑开始时相当乐观... 然后什么都没发生。过了很长时间,它继续写下20行像 和5行像 然后它输出一些结果 并更正其估计的eta: 我的是否比我想象的更频繁地被调用,或者还有什么其他原因导致了缓
线程池与任何ExecutorServices一样,我们定义了一个大小为3的newFixedPool。现在我有一个大约10000个可运行任务的队列。对于执行上述过程,我有这些疑问- > 要执行上述过程,执行者是否只允许来自任务queus的3个线程一次运行? 池将携带3个线程,这3个线程将只负责执行所有10000个任务。如果正确,单个线程如何运行不同的可运行任务,因为最终这些任务也是线程本身,并且在任
在Java中,什么与Python的pass等效?我意识到我可以使用continue语句或不完成语句体来实现这种效果,但我喜欢使用pass语句。
我的配置文件是类路径的路径。至少我认为是这样。我放置了log4j。资源文件夹中的属性文件,而log4j对此不做任何处理。即使我删除了它,也不会发生错误。 任何人都可以看到,我在使用maven LoggerTest的内容: 程序输出: log4j的内容。属性: 在波姆。xml并不是什么不同寻常的东西,只是一个依赖组织。阿帕奇。登录中。log4j log4j内核2.17.2,编译器源目标是16,没有插