Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从并发过渡到并行处理_Java_Multithreading - Fatal编程技术网

Java 从并发过渡到并行处理

Java 从并发过渡到并行处理,java,multithreading,Java,Multithreading,我有一个四核cpu,出于性能原因,我一直在尝试多线程。我在下面编写了这段代码,只是想看看它的速度有多快,我注意到它实际上比只使用主线程的第二个代码块慢 int numCrunchers = Runtime.getRuntime().availableProcessors(); public void crunch() { int numPairs = 1000; for(int i=0; i < numPairs; i++) pairs.add(...);

我有一个四核cpu,出于性能原因,我一直在尝试多线程。我在下面编写了这段代码,只是想看看它的速度有多快,我注意到它实际上比只使用主线程的第二个代码块慢

int numCrunchers = Runtime.getRuntime().availableProcessors();
public void crunch() {
    int numPairs = 1000;

    for(int i=0; i < numPairs; i++)
        pairs.add(...);

    int share = pairs.size()/numCrunchers;

    for(int i=0; i < numCrunchers; i++) {
        Cruncher cruncher = crunchers.get(i);

        for(int j=0; j < share; j++)
            cruncher.nodes.add(pairs.poll());
    }

    for(Cruncher cruncher : crunchers)
        threadpool.execute(cruncher);

    threadpool.shutdown();

    try {
        threadpool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

private class Cruncher implements Runnable {
    public BlockingQueue<Pair<PathNode>> nodes = new LinkedBlockingQueue<Pair<PathNode>>();
    private AStarPathfinder pathfinder;
    private LinkedList<PathNode> path = new LinkedList<PathNode>();

    public Cruncher(GridGraph graph) {
        pathfinder = new AStarPathfinder(graph);
    }

    @Override
    public void run() {
        while(true) {
            path.clear();
            Pair<PathNode> pair = nodes.poll();
            if(pair != null) {
                pathfinder.search(path, pair.first(), pair.second());
                paths.add(new LinkedList<PathNode>(path));
            } else {
                System.out.println("This cruncher is done");
                break;
            }
        }
    }
}
int numCrunchers=Runtime.getRuntime().availableProcessors();
公共空间紧缩{
int numPairs=1000;
for(int i=0;i
在我的电脑上,每个线程大约需要340000000000纳秒,但当我决定除了主线程之外不使用任何线程时,只需要1090195046纳秒,时间差为34倍

    LinkedList<Pair<PathNode>> pairs = new LinkedList<Pair<PathNode>>();
    int numPairs = 1000;
    AStarPathfinder pathfinder = new AStarPathfinder(graph);

    for(int i=0; i < numPairs; i++)
        pairs.add(...);

    long current = System.nanoTime();
    for(int i=0; i < numPairs; i++) {
        Pair<PathNode> pair = pairs.poll();
        path.clear();
        pathfinder.search(path, pair.first(), pair.second());
    }
    System.out.printf("Operation took %d nanoseconds", System.nanoTime() - current);
LinkedList pairs=新建LinkedList();
int numPairs=1000;
AStarPathfinder pathfinder=新的AStarPathfinder(图形);
for(int i=0;i
我的问题是为什么使用多线程会导致程序运行缓慢?代码是否没有正确地利用我cpu上的所有内核?我运行了好几次,结果是相似的,多线程和单线程之间的时间差是(30+x)

编辑: 决定测量多线程上每个单独操作的时间

    while(true) {
        path.clear();
        Pair<PathNode> pair = nodes.poll();
        if(pair != null) {
            long current = System.nanoTime();
            pathfinder.search(path, pair.first(), pair.second());
            paths.add(new LinkedList<PathNode>(path));
            System.out.printf("Took %d nanoseconds\n", System.nanoTime() - current);
        } else {
            System.out.println("This cruncher is done");
            break;
        }
    }
while(true){
path.clear();
Pair Pair=nodes.poll();
如果(对!=null){
长电流=System.nanoTime();
搜索(路径,pair.first(),pair.second());
添加(新链接列表(路径));
System.out.printf(“花费了%d纳秒\n”,System.nanoTime()-当前值);
}否则{
System.out.println(“这个紧缩器完成了”);
打破
}
}
和单线程

    LinkedList<Pair<PathNode>> pairs = new LinkedList<Pair<PathNode>>();
    int numPairs = 1000;
    AStarPathfinder pathfinder = new AStarPathfinder(graph);

    for(int i=0; i < numPairs; i++)
        pairs.add(...);

    for(int i=0; i < numPairs; i++) {
        long current = System.nanoTime();
        Pair<PathNode> pair = pairs.poll();
        path.clear();
        pathfinder.search(path, pair.first(), pair.second());
        System.out.printf("Operation took %d nanoseconds", System.nanoTime() - current);
    }
LinkedList pairs=新建LinkedList();
int numPairs=1000;
AStarPathfinder pathfinder=新的AStarPathfinder(图形);
for(int i=0;i

每个Cruncher都有自己的AStarPathfinder实例,因此pathfinder.search()不能在每个线程之间造成阻塞。多线程应用程序仍然慢得多。

这可能是由于多种原因造成的。创建和启动线程非常昂贵。线程之间的上下文切换也增加了这一点。尝试做一些需要几毫秒的事情。你也许会看到一些不同。尝试执行一个需要几秒钟时间的操作(在主线程上),您将(很可能)看到2代码块的性能发生了巨大变化。我将numPairs值更改为5000,并测量了每个cruncher内每次搜索所用的时间。这就是我发现的。在多线程应用程序上的每次搜索大约需要123235110到153037850纳秒,而在单线程应用程序上,最长的操作是2564662纳秒。向线程添加更多的工作似乎没有多大作用,而且似乎每个线程都共享一个核心。我想,仅仅创建线程(如上所述,成本很高)并将数据复制到线程(创建线程时串行执行)需要花费大量时间。由于咀嚼本身似乎不需要花费太多时间,因此执行750次甚至3750次额外的咀嚼仍然比所有的复制要短得多