当前位置: 首页 > 知识库问答 >
问题:

实现线程/可调用增加了我50%的执行时间,这是为什么呢?

贾建茗
2023-03-14

我目前正在深入研究多线程,但我在理解我当前在代码中做错了什么方面遇到了一些问题。

我试图通过调用我的“ThreadPopulateList()”来用随机数据填充2个列表,在我的理解中,这应该以Parralel启动2个线程。因为我调用了该方法两次。

但当我调用ThreadMethod时,执行时间会增加50%。这是为什么?如有任何帮助,我们将不胜感激!

public class Main {


public static void main(String[] args) throws IOException, ExecutionException, InterruptedException {
    long start=System.currentTimeMillis();

    /**Populate lists after eachother gives --> 4211 ms */
    //        List<DATA>list1normal = populateNormal(9999999);
    //        List<DATA>list2normal = populateNormal(9999999);

    /**Populate list simoultaniously/parralel --> 6500ms???*/
    List<DATA>list1normal = threadPopulateList(9999999);
    List<DATA>list2normal = threadPopulateList(9999999);

    long stop = System.currentTimeMillis();
    long executionTime = stop-start;
    System.out.println(executionTime+" ms");

}

/**Method to populate list*/
static List<DATA> populateNormal(int amount){
    List<DATA>data = new ArrayList<>();
    Random rn = new Random();
    for (int i = 0; i < amount; i++) {
        data.add(new DATA(rn.nextInt(1000),rn.nextInt(1000), rn.nextInt(1000)));
    }
    return data;
}

/**Method to start a thread for each call so list will populate simoultiously*/
static List<DATA> threadPopulateList(int amount) throws InterruptedException, ExecutionException {
    ExecutorService executor = Executors.newFixedThreadPool(2);
    List<DATA> data = new ArrayList<>();
    Random rn = new Random();
    Callable<List<DATA>> callable = () -> {
        for (int i = 0; i < amount; i++) {
            data.add(new DATA(rn.nextInt(1000), rn.nextInt(1000), rn.nextInt(1000)));
        }
        return data;
    };
    Future<List<DATA>> result = executor.submit(callable);
    executor.shutdown();
    return result.get();
   }
}

共有1个答案

龚永新
2023-03-14

callable是要执行的任务。您的代码只有一个callable,因此它只能在一个线程上执行。

即使您创建了一个包含两个线程的ThreadPool,但由于您只有一个任务,因此保证其中一个线程是空闲的。

此外,您要填写两次列表,因此您的一个任务将是您填写一次列表时的两倍。

我将尝试创建两个callable,每个callable来处理列表中1/2的数据;然后安排他们两个。一旦它们都完成了,将结果合并到最终的“输出”列表中。

您的解决方案只增加了50%的时间,而不是100%的时间,这是因为您的基准测试可能包括启动JVM和开始处理的时间。这意味着您对原始程序的总体分解可能是“执行时间=启动时间+处理时间”,其中启动时间大约是执行时间的1/2。

 类似资料:
  • 我有以下Thread子类(为了易读性稍微简化): 当我连接到服务器时,这个线程的一个实例是由我的客户端(使用Swing GUI)创建的。我觉得奇怪的是,我可以从主GUI调用方法,而且它是有效的。为什么无限而循环和/或调用不会阻止我这样做?我的意思是线程不应该一直忙于做其他事情吗?这是做事的好方法吗?如果不是,为什么不呢? 编辑 为了澄清我的困惑:如果这是在主线程中,它将在中的直到读取了某个内容,然

  • 我正在使用EclipseIDE编程。在完成有关Apache POI的教程后: https://www.youtube.com/watch?v=RsrF2Ku7ad4 我通过eclipse和以下链接创建了一个可执行jar:http://help.eclipse.org/mars/index.jsp?topic=/org.eclipse.jdt.doc.user/tasks/tasks-37.htm

  • 在添加新的键值对时,我有几个关于重建哈希映射的问题。我将根据这些事实提出问题(它们对于Oracle JVM是正确的,不确定它们对于其他JVM是否正确): 每次当HashMap增长大于阈值(阈值=加载因子*条目数)时,Resize将重建HashMap,使其具有更大的内部表数组。新创建的条目放在哪个存储桶中并不重要,Map仍然会变得更大。即使所有条目都进入一个bucket(即它们的键“返回相同的数字)

  • 问题内容: 还是Scala的新手,我现在正在寻找一种在其上实现以下代码的方法: 在Scala中实现与RetryableService实现的功能相同的最佳方法是什么? 它基本上调用N次 调用 方法,如果所有方法均失败,则引发异常,如果所有方法均失败,则继续进行。这个不返回任何内容,但是我有另一个版本可以返回值(因此,我在Java中有两个类),我相信我可以在Scala中使用单个类/函数。 有任何想法吗

  • 代码只是从输入源获取ip数据,然后在加入后找到它的公司。以下是我的问题: 这段代码在生产中会运行2-3分钟,但当删除广播数据(只需在两个数据上连接)时,只需花费不到1分钟。当我查看spark的ui时,我发现gc时间可能是问题所在。 下面是运行此作业的设置: null 更新2。由于生产代码相当复杂,与上面的伪代码不同,在代码顺序上稍作改变后,程序运行得更快,但我不确定问题的关键是初始化广播数据的位置