Java线程池限制已创建的最大线程数
我正试图编写一个Java多线程程序,对作为文件给出的2个矩阵执行乘法,并使用有限的线程总数 例如,如果我将线程数设置为16,我希望我的线程池能够重用这16个线程,直到所有任务完成 然而,对于更多的线程,我最终会有更大的执行时间,我很难理解为什么 可运行:Java线程池限制已创建的最大线程数,java,multithreading,matrix-multiplication,java-threads,Java,Multithreading,Matrix Multiplication,Java Threads,我正试图编写一个Java多线程程序,对作为文件给出的2个矩阵执行乘法,并使用有限的线程总数 例如,如果我将线程数设置为16,我希望我的线程池能够重用这16个线程,直到所有任务完成 然而,对于更多的线程,我最终会有更大的执行时间,我很难理解为什么 可运行: class Task implements Runnable { int _row = 0; int _col = 0; public Task(int row, int col) { _row
class Task implements Runnable
{
int _row = 0;
int _col = 0;
public Task(int row, int col)
{
_row = row;
_col = col;
}
@Override
public void run()
{
Application.multiply(_row, _col);
}
}
public class Application
{
private static Scanner sc = new Scanner(System.in);
private static int _A[][];
private static int _B[][];
private static int _C[][];
public static void main(final String [] args) throws InterruptedException
{
ExecutorService executor = Executors.newFixedThreadPool(16);
ThreadPoolExecutor pool = (ThreadPoolExecutor) executor;
_A = readMatrix();
_B = readMatrix();
_C = new int[_A.length][_B[0].length];
long startTime = System.currentTimeMillis();
for (int x = 0; x < _C.length; x++)
{
for (int y = 0; y < _C[0].length; y++)
{
executor.execute(new Task(x, y));
}
}
long endTime = System.currentTimeMillis();
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.HOURS);
System.out.printf("Calculation Time: %d ms\n" , endTime - startTime);
}
public static void multMatrix(int row, int col)
{
int sum = 0;
for (int i = 0; i < _B.length; i++)
{
sum += _A[row][i] * _B[i][col];
}
_C[row][col] = sum;
}
...
}
应用程序:
class Task implements Runnable
{
int _row = 0;
int _col = 0;
public Task(int row, int col)
{
_row = row;
_col = col;
}
@Override
public void run()
{
Application.multiply(_row, _col);
}
}
public class Application
{
private static Scanner sc = new Scanner(System.in);
private static int _A[][];
private static int _B[][];
private static int _C[][];
public static void main(final String [] args) throws InterruptedException
{
ExecutorService executor = Executors.newFixedThreadPool(16);
ThreadPoolExecutor pool = (ThreadPoolExecutor) executor;
_A = readMatrix();
_B = readMatrix();
_C = new int[_A.length][_B[0].length];
long startTime = System.currentTimeMillis();
for (int x = 0; x < _C.length; x++)
{
for (int y = 0; y < _C[0].length; y++)
{
executor.execute(new Task(x, y));
}
}
long endTime = System.currentTimeMillis();
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.HOURS);
System.out.printf("Calculation Time: %d ms\n" , endTime - startTime);
}
public static void multMatrix(int row, int col)
{
int sum = 0;
for (int i = 0; i < _B.length; i++)
{
sum += _A[row][i] * _B[i][col];
}
_C[row][col] = sum;
}
...
}
公共类应用程序
{
专用静态扫描仪sc=新扫描仪(System.in);
私有静态int_A[];
私有静态int_B[];
私有静态int_C[];
公共静态void main(最终字符串[]args)引发InterruptedException
{
ExecutorService executor=Executors.newFixedThreadPool(16);
ThreadPoolExecutor池=(ThreadPoolExecutor)执行器;
_A=读取矩阵();
_B=读取矩阵();
_C=新整数[_A.length][_B[0].length];
long startTime=System.currentTimeMillis();
对于(int x=0;x<_C.length;x++)
{
对于(int y=0;y<\u C[0]。长度;y++)
{
执行者。执行(新任务(x,y));
}
}
long-endTime=System.currentTimeMillis();
executor.shutdown();
执行者等待终止(长最大值,时间单位,小时);
System.out.printf(“计算时间:%d ms\n”,结束时间-开始时间);
}
公共静态无效多维矩阵(整数行,整数列)
{
整数和=0;
对于(int i=0;i<_B.length;i++)
{
总和+=_A[行][i]*_B[i][col];
}
_C[行][列]=和;
}
...
}
矩阵计算和工作负载共享似乎是正确的,因此可能是由于错误使用了ThreadPool使用submit而不是execute 将返回的
Future
s列一个列表,以便您可以等待它们
List<Future<?>> futures = new ArrayList<>();
futures.add(executor.submit(new Task(x, y)));
列表使用提交而不是执行
将返回的Future
s列一个列表,以便您可以等待它们
List<Future<?>> futures = new ArrayList<>();
futures.add(executor.submit(new Task(x, y)));
List这些线程已经被重用以执行任务,这是ThreadPoolExecutor的预期行为
随着线程名称的增加,计算时间也会增加,因为创建线程所需的时间大于执行相对较短的任务时并发性所带来的性能改善。这些线程已经被重用以执行任务,这是ThreadPoolExecutor的预期行为
随着线程名称的增加,计算时间也会增加,因为创建线程所需的时间比执行相对较短的任务时并发性所带来的性能改善要长。上下文切换需要时间。
如果您有8个内核,并且您正在执行8个线程,那么它们都可以同时工作,并且一旦一个内核完成,它将被重用。
另一方面,如果8个内核有16个线程,那么每个线程都将争夺处理器时间,调度程序将切换这些线程,您的时间将增加到-执行时间+上下文切换
线程越多,上下文切换就越多,因此时间也就越长 上下文切换需要时间。
如果您有8个内核,并且您正在执行8个线程,那么它们都可以同时工作,并且一旦一个内核完成,它将被重用。
另一方面,如果8个内核有16个线程,那么每个线程都将争夺处理器时间,调度程序将切换这些线程,您的时间将增加到-执行时间+上下文切换
线程越多,上下文切换就越多,因此时间也就越长 请注意,通常,要创建的最佳线程数(即限制线程池)是CPU中的核心数量:CPU可以执行多少线程?当您有多个处理器(核心)来处理它们时,多个线程实际上很有用。我有8个可用的处理器。我并不是在寻找最佳线程数,而是用指定的线程数运行程序,并利用这些线程执行所有任务是CPU中的核心数量:您的CPU可以执行多少线程?当您有多个处理器(核心)来处理它们时,多个线程实际上非常有用。我有8个可用的处理器。我并没有试图找到最佳的线程数,只是用指定的线程数运行程序,并利用这些线程来执行所有任务。我已经尝试过了,但它并没有改变我的执行时间。使用更多线程仍然需要更多的时间。已尝试此操作,但它不会更改我的执行时间。更多的线程仍然需要更多的时间。感谢我理解的澄清,感谢我理解的澄清,我以前从未听说过上下文切换,但我现在明白了。谢谢你的解释。以前从未听说过上下文转换,但现在我明白了。谢谢你的解释。