我编码了….我相信我的方法是对的,但我不是百分百肯定.关于线程,我不明白为什么我不能只运行(new MatrixThread(…)).start()而不是使用ExecutorService.
另外,当我对……方法与经典方法进行基准测试时,经典方法要快得多……
我究竟做错了什么?
附:如果需要进一步说明,请与我们联系.
发送线程也没有必要执行;它需要的只是一个Runnable.通过应用这些更改,您将获得巨大的性能提升:
>使ExecutorService成为静态成员,为当前处理器调整大小,并向其发送一个ThreadFactory,以便在main完成后不保持程序运行. (将它作为参数发送到方法而不是将其保持为静态字段可能在架构上更清晰;我将其留作读者的练习.☺)
private static final ExecutorService workerPool =
Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(),new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
});
>使MatrixThread实现Runnable而不是继承Thread.线程创建起来很昂贵; POJO非常便宜.您还可以将其设置为静态,这会使实例变小(因为非静态类会获得对封闭对象的隐式引用).
private static class MatrixThread implements Runnable
>从更改(1),您不能再awaitTermination来确保所有任务都已完成(作为此工作池).而是使用submit方法返回Future<?>.收集列表中的所有未来对象,当您提交了所有任务时,迭代列表并为每个对象调用get.
你的乘法方法现在应该是这样的:
public Matrix multiply(Matrix multiplier) throws InterruptedException {
Matrix result = new Matrix(dimension);
List
它会比单线程版本更快吗?好吧,在我可以说是糟糕的盒子上,多线程版本的n值为n< 1024. 不过,这只是表面上的问题.真正的问题是你创建了很多MatrixThread实例 – 你的内存消耗是O(n²),这是一个非常糟糕的迹象.将内部for循环移动到MatrixThread.run可以通过craploads来提高性能(理想情况下,您不会创建比工作线程更多的任务). 编辑:由于我有更多紧迫的事情要做,我无法抗拒进一步优化.我想出了这个(……极其难看的代码片段),“只”创造了O(n)工作:
public Matrix multiply(Matrix multiplier) throws InterruptedException {
Matrix result = new Matrix(dimension);
List
它仍然不是很好,但基本上多线程版本可以计算你耐心等待的任何东西,并且它比单线程版本更快.