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

并发/多线程什么时候有助于提高性能?

公西俊能
2023-03-14

在学习了并发之后,我一直计划在项目中使用并发。现在我没有在多线程或并发上做太多工作,所以决定在实际项目中使用它之前学习并进行一个简单的概念验证。
以下是我尝试过的两个例子:

1. With use of concurrency

    public static void main(String[] args) 

    {
        System.out.println("start main ");

        ExecutorService es = Executors.newFixedThreadPool(3);
        long startTime = new Date().getTime();
        Collection<SomeComputation> collection = new ArrayList<SomeComputation>();
        for(int i=0; i< 10000; i++){
            collection.add(new SomeComputation("SomeComputation"+i));
        }
        try {
            List<Future< Boolean >> list = es.invokeAll(collection);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("\n end main "+(new Date().getTime() - startTime));
    }

2. Without use of concurrency

        public static void main(String[] args) {

          System.out.println("start main ");
          long startTime = new Date().getTime();
          Collection<SomeComputation> collection = new ArrayList<SomeComputation>();
          for(int i=0; i< 10000; i++){
          collection.add(new SomeComputation("SomeComputation"+i));
        }
        for(SomeComputation sc:collection)
        {
        sc.compute();
        }
        System.out.println("\n end main "+(new Date().getTime() - startTime));
        }

    Both share a common class

        class SomeComputation implements Callable<Boolean>
        {
            String name;
            SomeComputation(String name){this.name=name;}
            public Boolean compute()
            {
                someDumbStuff();
                return true;
            }

            public Boolean call()
            {
                someDumbStuff();
                return true;
            }

            private void someDumbStuff()
            {
                for (int i = 0;i<50000;i++)
                {
                    Integer.compare(i,i+1);
                }
                System.out.print("\n done with "+this.name);
            }
        }

现在,在每种方法运行了20多次之后进行分析
第一次并发平均需要451毫秒
第二个无并发的平均时间为290毫秒
现在我了解到这取决于配置、操作系统、版本(java7)和处理器。但这两种方法都是一样的。还了解到,当计算量很大时,并发的成本是可以承受的。但这一点我并不清楚。
希望有人能帮助我更了解这一点
附言:我试过寻找类似的问题,但却能找到这种问题。如果你这样做,请评论链接。

共有3个答案

顾均
2023-03-14

当线程共享相同的数据源时,需要并发性,因此当一些线程处理该数据源时,其他线程必须等到它完成任务后才能访问,因此您需要学习同步方法和bluck或类似的东西抱歉,我的英语不好,请阅读此教程,它很有帮助https://docs . Oracle . com/javase/tutorial/essential/concurrency/sync meth . html

卫招
2023-03-14

正如在一个回答中提到的,并发的一个用途是简化代码,也就是说,某些问题在逻辑上是并发的,因此没有办法以非并发的方式对这些问题建模,如生产者-消费者问题、web请求的侦听器等

除此之外,并发程序只有在能够为您节省CPU周期时才能提高性能,即目标是让CPU或CPU一直保持忙碌,而不是浪费其周期,这进一步意味着当您的程序应该忙于非CPU任务时,您可以让CPU做一些有用的事情,例如等待磁盘I/O、等待锁、睡眠、GUI应用程序用户等待等-这些时间只是将时间添加到您的总程序运行时间中。

所以问题是,当你的程序不使用CPU时,它会做什么?我可以在这段时间内完成程序的一部分,并将等待部分隔离到另一个线程中吗?现在,大多数现代系统都是多处理器和多核系统,如果程序不是并发的,则进一步导致浪费。

您编写的示例是在内存中执行所有处理而不进入任何等待状态,因此您看不到太多收益,而只是在设置线程和上下文切换时看到损失。

尝试通过点击数据库来衡量性能,获取100万记录,处理这些记录,然后再次将这些记录保存到数据库。一次完成,顺序完成,并以并发方式小批量完成,这样您就会注意到性能差异,因为数据库操作是磁盘密集型的,当您读取或写入数据库时,您实际上是在执行磁盘I/O,而CPU在此期间可以自由浪费其周期。

在我看来,并发性的好候选对象是涉及上面提到的等待操作之一的长时间运行的任务,否则您不会看到太多好处。需要一些后台任务的程序也是并发性的好候选。

并发不必与CPU的多任务处理混淆,即当您在同一CPU上同时运行不同的程序时。

希望它有帮助!

凤修筠
2023-03-14

并发至少有两个不同的目的:1)性能,和2)代码的简单性(就像web请求的1000个监听器)。

如果你的目标是性能,那么你不能得到比你投入工作的硬件核心数量更多的加速。(只有当线程受CPU限制时才会这样。)此外,每个线程都有很大的启动开销。因此,如果你在4核机器上启动1000个线程,你不可能比4倍的速度做得更好,但与此相反,你有1000个线程的启动成本。

 类似资料:
  • 本文向大家介绍SVM中什么时候用线性核什么时候用高斯核?相关面试题,主要包含被问及SVM中什么时候用线性核什么时候用高斯核?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 当数据的特征提取的较好,所包含的信息量足够大,很多问题是线性可分的那么可以采用线性核。若特征数较少,样本数适中,对于时间不敏感,遇到的问题是线性不可分的时候可以使用高斯核来达到更好的效果。

  • 在java编程中,什么时候需要考虑并发编程来保证线程安全性。还没深入了解这块,在编程时一直很犹豫。

  • 问题内容: 我知道Deamon是后台线程。我们可以通过调用创建自己的守护程序线程。 我的问题是:为什么以及何时需要将我们的线程创建为守护程序线程? 问题答案: 当所有正在运行的线程都是守护程序线程时,JVM将退出。因此,想象一下您正在编写一个简单的游戏,其中您的主要方法一直循环直到您决定退出为止。想象一下,在游戏开始时,您启动了一个线程,该线程将不断轮询某些网站以触发警报。当您决定结束游戏时,您希

  • 我目前正在我的应用程序中使用Guice。然而,我发现自己大多使用辅助注入,因为有一个注入对象链,它们都依赖于程序的输入。因此几乎所有的东西都是辅助注射的。 例如,A需要B,B需要c,c需要Z,Z需要来自命令行的输入。最后我感觉一切都将被辅助注射。因此,鉴于我坚持使用它,我想确定我使用它是正确的。 我个人觉得写我自己的工厂也一样好。此外,除了同样的优点之外,我还可以进一步将我所讨论的对象的创建限制在

  • 问题内容: 因此,我对Node.js的工作方式有所了解:它具有一个侦听器线程,该线程接收事件,然后将其委托给工作池。工作线程一旦完成工作,便会通知侦听器,然后侦听器将响应返回给调用者。 我的问题是:如果我在Node.js中建立一个HTTP服务器,并在我的一个路由路径事件(例如“ / test / sleep”)中调用sleep,那么整个系统就会停顿下来。甚至是单个侦听器线程。但是我的理解是这段代码

  • Java 是最先支持多线程开发的语言之一, Java 多线程和并发也是 Java 学习的重点加难点。本教程根据作者多年 Java 开发经验总结而成,旨在帮助读者明白并发的原理。