gpt4 book ai didi

java - 为什么这段Java代码没有并发运行

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:16:56 25 4
gpt4 key购买 nike

我编写了 Sieve of Eratosthenes,它应该并行工作,但事实并非如此。当我增加线程数时,计算时间并没有变短。有什么想法吗?

主类

import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ConcurrentTest {
public static void main(String[] args) throws InterruptedException {
Sieve task = new Sieve();
int x = 1000000;
int threads = 4;
task.setArray(x);
Long beg = new Date().getTime();
ExecutorService exec = Executors.newCachedThreadPool();
for (int i = 0; i < threads; i++) {
exec.execute(task);
}
exec.shutdown();
Long time = 0L;
// Main thread is waiting until all threads are terminated
// ( it means that computing is done)
while (true)
if (exec.isTerminated()) {
time = new Date().getTime() - beg;
break;
}

System.out.println("Time is " + time);
}
}

筛级

import java.util.concurrent.ConcurrentHashMap;

public class Sieve implements Runnable {
private ConcurrentHashMap<Integer, Boolean> array =
new ConcurrentHashMap<Integer, Boolean>();
private int x;
public void run() {
while(true){
// I am getting synchronized number to check if it's prime
int n = getCounter();
// If no more numbers to check, stop loop
if( n == -1)
break;
// If HashMap contains number, we can further
if(!array.containsKey(n))continue;
for (int i = 2 * n; i <= x; i += n) {
// Compound numbers are removed from HashMap, Eg. 6, 12 and much more.
array.remove(i);
}
}
}
private synchronized int getCounter(){
if( counter < x)
return counter++;
else return -1;
}
public void setArray(int x) {
this.x = x;
for (int i = 2; i <= x; i++)
array.put(i, false);
}
}

我用不同数量的线程做了一些测试。这些是结果:

Nr of threads 1    Time is 1850, 1795, 1825
Nr of threads 2 Time is 1845, 1836, 1814
Nr of threads 3 Time is 1767, 1820, 1756
Nr of threads 4 Time is 1732, 1840, 2083
Nr of threads 5 Time is 1791, 1795, 1803
Nr of threads 6 Time is 1825, 1728, 1707
Nr of threads 7 Time is 1754, 1729, 1686
Nr of threads 8 Time is 1760, 1717, 1817
Nr of threads 9 Time is 1721, 1699, 1673
Nr of threads 10 Time is 1661, 1722, 1718

最佳答案

When I increase number of threads, time of computing is not getting lower

tl;dr:您的问题规模太小。如果将 x 增加到 10000000,差异将变得更加明显。不过,它们不会是您所期望的那样。

我在八核机器上测试了你的代码,做了两处细微的修改:

  1. 对于计时,我使用了 System.nanoTime()而不是日期上的 getTime()。
  2. 我使用了 awaitTermination ExecutorService 方法而不是自旋循环来检查运行结束。

我尝试使用 fixed thread pool 启动您的 Sieve 任务, 一个 cached thread pool和一个 fork join pool并比较线程变量的不同值的结果。

我在 x=10000000 的机器上看到以下结果(以毫秒为单位):

    Thread count      = 1    2    4    8    16    Fixed thread pool = 5451 3866 3639 3227 3120    Cached thread pool= 5434 3763 3709 3258 3078    Fork-join pool    = 6732 3670 3735 3190 3102

这些结果向我们展示了从单个执行线程更改为两个线程的明显好处。但是,额外线程的好处会迅速下降。有一个有趣的平台,从两个线程到四个线程,边际 yield 高达 16。

此外,您还可以看到不同的线程机制具有不同的初始开销:我没想到 Fork-Join 池的启动成本比其他机制高得多。

因此,正如所写的那样,对于小型但重要的问题集,您不应该真正期待超过两个线程的好处。

如果您想增加额外线程的好处,您将需要查看您当前的实现。例如,当我从同步的 getCounter() 切换到 AtomicInteger 时使用 incrementAndGet() ,我消除了同步方法的开销。结果是我的四个线程号都下降了大约 1000 毫秒。

关于java - 为什么这段Java代码没有并发运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18681953/

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