有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么newFixedThreadPool的增量会导致性能低下?

我正在尝试更改报表的执行,并使其并发完成。在“串行模式”中,执行测试需要30秒,而在使用并发模式时,我需要27秒(考虑到串行模式中必须执行的步骤很少,我对结果没有意见)

我还是不明白这句话:

ExecutorService executor = Executors.newFixedThreadPool(4);

我的电脑配备了2x2。6 Ghz四核,如果newFixedThreadPool高(16),我希望执行时间会减少。实际上,增加newFixedThreadPool越多,执行速度就越慢。这就引出了一个问题:我做错了什么,或者我没有理解什么

我正在嵌入我执行的2个结果截图

A.newSingleThreadExecuter-运行时间为23秒

B.newFixedThreadPool(4)-运行时间为43秒

每次我提交“Worker”时,我都会得到一个系统。输出currentTimeMillis,“fatched tkt”结果是从数据库获取数据所需的毫秒数。(在策略A中-需要3毫秒,在B中需要7毫秒)

    Stopper stopper = new Stopper();
    for (Long iNum : multimap.asMap().keySet())
    {
        List<Long> tickets = (List<Long>) multimap.get(iNum);
        for (Long ticketNumber : tickets)
        {
                pojoPks = getPkData(iNum);
                Callable<PojoTicket> worker = new MaxCommThread(ticketNumber, pojoPks);
                Future<PojoTicket> submit = executor.submit(worker);
                futures.add(submit);
        }
    }

    System.out.println("futurues: " +futures.size());
    for (Future<PojoTicket> future : futures)
    {
        try
        {
            PojoTicket pojoTicket = future.get();
            //do the rest here

        } catch (InterruptedException e)
        {
            System.out.println("---------------------->InterruptedException");
        } catch (ExecutionException e)
        {
            System.out.println("---------------------->ExecutionException");
        }
    }

    executor.shutdown();
    stopper.stop();

enter image description here

enter image description here


共 (1) 个答案

  1. # 1 楼答案

    the more I increase the newFixedThreadPool the slower the execution

    一般来说,如果在作业中添加线程,但没有加快速度,可能是因为以下原因之一:

    • 每个作业都必须在某种资源上同步,因此它们都在为锁争用而斗争,而不是独立运行

    • 这些作业没有多少CPU工作要做。向IO绑定的进程添加线程不会加快进程的运行速度,因为IO通道可能已经耗尽

    然而,如果您的应用程序运行速度只有原来的一半,这是一个有趣的情况。我只能猜测这是两者的结合

    要尝试的一件事是从1个线程开始,然后尝试2个线程。如果运行速度不快,那么首先看看作业之间共享了哪些锁。每个作业正在修改哪些并发集合或其他对象?尝试减少锁的数量,或者让线程存储临时信息,然后锁定一次以更新中心对象

    你也可以观察你的系统统计数据,看看你的IO通道是否达到最大值。磁盘是一个常见的问题。查看是否可以在内存磁盘上运行,以查看应用程序是否运行得更快。这将是一个指标,表明你是IO绑定

    最后,我想探讨一下,当你的工作得到收获时,为什么你会得到任何ExecutionException。这可能是其他问题的一个迹象,但你应该首先理解这一点