带Executor和不带Executor的多线程区别

2023-12-27

我试图找出普通多线程和使用执行器的多线程(维护线程池)之间的性能差异。

以下是两者的代码示例。

没有执行器代码(使用多线程):

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.ThreadMXBean;
import java.util.List;

public class Demo1 {
public static void main(String arg[]) {
    Demo1 demo = new Demo1();
    Thread t5  = new Thread(new Runnable() {
       public void run() {
              int count=0;
              // Thread.State;
              // System.out.println("ClientMsgReceiver started-----");
              Demo1.ChildDemo  obj = new Demo1.ChildDemo();
              while(true) {

                // System.out.println("Threadcount is"+Thread);
                // System.out.println("count is"+(count++));
                Thread t=new Thread(obj);
                t.start();
                ThreadMXBean tb = ManagementFactory.getThreadMXBean();
                List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
                for (MemoryPoolMXBean pool : pools) {
                   MemoryUsage peak = pool.getPeakUsage();
                   System.out.format("Peak %s memory used: %,d%n",
                             pool.getName(), peak.getUsed());
                   System.out.format("Peak %s memory reserved: %,d%n",
                             pool.getName(), peak.getCommitted());
                } 

                System.out.println("Current Thread Count"+ tb.getThreadCount());
                System.out.println("Peak Thread Count"+ tb.getPeakThreadCount());
                System.out.println("Current_Thread_Cpu_Time " 
                         + tb.getCurrentThreadCpuTime());
                System.out.println("Daemon Thread Count" +tb.getDaemonThreadCount());
       }
       // ChatLogin = new ChatLogin();
     }
  });
  t5.start();
}

static class ChildDemo implements Runnable {
   public void run() {
        try {
        //  System.out.println("Thread Started with custom Run method");
            Thread.sleep(100000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally {
            System.out.println("A" +Thread.activeCount());
        }
    }
  }
}

使用执行器(多线程):

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.ThreadMXBean;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Executor_Demo {
public static void main(String arg[]) {
   BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(10);
   ThreadPoolExecutor executor   = new ThreadPoolExecutor(
          10, 100, 10, TimeUnit.MICROSECONDS, queue);
   Executor_Demo demo = new Executor_Demo();

   executor.execute(new Runnable() {
       public void run() {
          int count=0;
          // System.out.println("ClientMsgReceiver started-----");
          Executor_Demo.Demo demo2 = new Executor_Demo.Demo();
          BlockingQueue<Runnable> queue1 = new ArrayBlockingQueue<Runnable>(1000);
          ThreadPoolExecutor executor1   = new ThreadPoolExecutor(
                  1000, 10000, 10, TimeUnit.MICROSECONDS, queue1);

          while(true) {
             // System.out.println("Threadcount is"+Thread);
             // System.out.println("count is"+(count++));
             Runnable command= new Demo();
             // executor1.execute(command);
             executor1.submit(command);         
             // Thread t=new Thread(demo2);
             // t.start();
             ThreadMXBean tb = ManagementFactory.getThreadMXBean();
             /* try {
                  executor1.awaitTermination(100, TimeUnit.MICROSECONDS);
                } catch (InterruptedException e) {
                   // TODO Auto-generated catch block
                   e.printStackTrace();
                } */
              List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
              for (MemoryPoolMXBean pool : pools) {
                 MemoryUsage peak = pool.getPeakUsage();
                 System.out.format("Peak %s memory used: %,d%n",
                          pool.getName(), peak.getUsed());
                 System.out.format("Peak %s memory reserved: %,d%n",
                          pool.getName(), peak.getCommitted());
          }
              System.out.println("daemon threads"+tb.getDaemonThreadCount());
              System.out.println("All threads"+tb.getAllThreadIds());
              System.out.println("current thread CPU time "
                       + tb.getCurrentThreadCpuTime());
              System.out.println("current thread user time "
                       + tb.getCurrentThreadUserTime());
              System.out.println("Total started thread count " 
                       + tb.getTotalStartedThreadCount());
              System.out.println("Current Thread Count"+ tb.getThreadCount());
              System.out.println("Peak Thread Count"+ tb.getPeakThreadCount());
              System.out.println("Current_Thread_Cpu_Time " 
                       + tb.getCurrentThreadCpuTime());
              System.out.println("Daemon Thread Count"
                       + tb.getDaemonThreadCount());
              // executor1.shutdown();  
            }
            //ChatLogin = new ChatLogin();
          }
     });
     executor.shutdown();
}

static class Demo implements Runnable {
    public void run() {
      try {
        // System.out.println("Thread Started with custom Run method");
        Thread.sleep(100000);
      } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
      finally {
         System.out.println("A" +Thread.activeCount());
      }
   }
  }
}

Sample output Output

当我运行这两个程序时,发现执行器比普通的多线程更昂贵。为什么会这样呢?

那么执行器到底有什么用呢?我们使用执行器来管理线程池。

我希望执行器能够提供比普通多线程更好的结果。

基本上我这样做是因为我需要使用带有多线程的套接字编程来处理数百万个客户端。

任何建议都会有帮助。


为了了解某些东西如何扩展,我会尽力将监控成本​​保持在最低限度,并且我会比较一个小数字和一个大数字。

public class Executor_Demo {
    public static void main(String... arg) throws ExecutionException, InterruptedException {
        int nThreads = 5100;
        ExecutorService executor = Executors.newFixedThreadPool(nThreads, new DaemonThreadFactory());

        List<Future<Results>> futures = new ArrayList<Future<Results>>();
        for (int i = 0; i < nThreads; i++) {
            futures.add(executor.submit(new BackgroundCallable()));
        }
        Results result = new Results();
        for (Future<Results> future : futures) {
            result.merge(future.get());
        }
        executor.shutdown();

        result.print(System.out);

    }

    static class Results {
        private long cpuTime;
        private long userTime;

        Results() {
            final ThreadMXBean tb = ManagementFactory.getThreadMXBean();
            cpuTime = tb.getCurrentThreadCpuTime();
            userTime = tb.getCurrentThreadUserTime();
        }


        public void merge(Results results) {
            cpuTime += results.cpuTime;
            userTime += results.userTime;
        }

        public void print(PrintStream out) {
            ThreadMXBean tb = ManagementFactory.getThreadMXBean();

            List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
            for (int i = 0, poolsSize = pools.size(); i < poolsSize; i++) {
                MemoryPoolMXBean pool = pools.get(i);
                MemoryUsage peak = pool.getPeakUsage();
                out.format("Peak %s memory used:\t%,d%n", pool.getName(), peak.getUsed());
                out.format("Peak %s memory reserved:\t%,d%n", pool.getName(), peak.getCommitted());
            }

            out.println("Total thread CPU time\t" + cpuTime);
            out.println("Total thread user time\t" + userTime);
            out.println("Total started thread count\t" + tb.getTotalStartedThreadCount());
            out.println("Current Thread Count\t" + tb.getThreadCount());
            out.println("Peak Thread Count\t" + tb.getPeakThreadCount());
            out.println("Daemon Thread Count\t" + tb.getDaemonThreadCount());
        }
    }

    static class DaemonThreadFactory implements ThreadFactory {
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            t.setDaemon(true);
            return t;
        }
    }

    static class BackgroundCallable implements Callable<Results> {
        @Override
        public Results call() throws Exception {
            Thread.sleep(100);
            return new Results();
        }
    }
}

当测试时-XX:MaxNewSize=64m(这限制了临时内存空间的大小会增加)

100 threads
Peak Code Cache memory used:    386,880
Peak Code Cache memory reserved:    2,555,904
Peak PS Eden Space memory used: 41,280,984
Peak PS Eden Space memory reserved: 50,331,648
Peak PS Survivor Space memory used: 0
Peak PS Survivor Space memory reserved: 8,388,608
Peak PS Old Gen memory used:    0
Peak PS Old Gen memory reserved:    192,675,840
Peak PS Perm Gen memory used:   3,719,616
Peak PS Perm Gen memory reserved:   21,757,952
Total thread CPU time   20000000
Total thread user time  20000000
Total started thread count  105
Current Thread Count    93
Peak Thread Count   105
Daemon Thread Count 92

5100 threads
Peak Code Cache memory used:    425,728
Peak Code Cache memory reserved:    2,555,904
Peak PS Eden Space memory used: 59,244,544
Peak PS Eden Space memory reserved: 59,244,544
Peak PS Survivor Space memory used: 2,949,152
Peak PS Survivor Space memory reserved: 8,388,608
Peak PS Old Gen memory used:    3,076,400
Peak PS Old Gen memory reserved:    192,675,840
Peak PS Perm Gen memory used:   3,787,096
Peak PS Perm Gen memory reserved:   21,757,952
Total thread CPU time   810000000
Total thread user time  150000000
Total started thread count  5105
Current Thread Count    5105
Peak Thread Count   5105
Daemon Thread Count 5104

主要的增加是旧一代使用量的增加约 3 MB 或每个线程约 6 KB。 CPU 使用时间为 956 毫秒,即每个线程大约 0.2 毫秒。


在第一个示例中,您创建一个线程,在第二个示例中您创建 1000 个线程。

您正在执行的输出似乎是大部分工作,并且第二种情况下的输出比第一种情况要多得多。

您需要确保您的测试和监控比您想要监控/测量的要轻得多。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

带Executor和不带Executor的多线程区别 的相关文章

  • 在不支持 CAS 操作的处理器上进行 CompareAndSet

    今天 我在一次采访中被问到下一个问题 如果您在具有不支持 CAS 操作的处理器的机器上调用 AtomicLong 的compareAndSet 方法 会发生什么情况 您能否帮我解决这个问题 并在可能的情况下提供一些全面描述的链接 From
  • Kafka - 如何同时使用过滤器和过滤器?

    我有一个 Kafka 流 它从一个主题获取数据 并且需要将该信息过滤到两个不同的主题 KStream
  • 如何以编程方式使用包含多列的 where-in 子句执行 PostgreSQL 查询?

    我的查询是这样的 select from plat customs complex where code t code s in 01013090 10 01029010 90 它在 psql 控制台中运行良好 我的问题是如何在客户端代码中
  • 通过Zuul上传大文件

    我在通过 zuul 上传大文件时遇到问题 我正在使用 apache commons 文件上传 https commons apache org proper commons fileupload https commons apache o
  • Python 中 time.sleep 和多线程的问题

    我对 python 中的 time sleep 函数有疑问 我正在运行一个脚本 需要等待另一个程序生成 txt 文件 虽然 这是一台非常旧的机器 所以当我休眠 python 脚本时 我遇到了其他程序不生成文件的问题 除了使用 time sl
  • 如何使用 Java Apache POI 隐藏 Excel 工作表中以下未使用的行?

    我正在使用数据库中的数据填充模板 Excel 工作表 for Map
  • 单线程程序中可以有竞争条件吗?

    您可以在here https en wikipedia org wiki Race condition Software关于什么是竞争条件的一个很好的解释 我最近看到很多人对竞争条件和线程做出了令人困惑的陈述 我了解到竞争条件只能发生在线程
  • 如何在 IntelliJ IDEA 中运行 akka actor

    来自 Akka 网站文档 然后 这个主要方法将创建所需的基础设施 运行演员 启动给定的主要演员并安排 一旦主要参与者终止 整个应用程序就会关闭 因此 您将能够使用类似于以下的命令运行上面的代码 下列的 java classpath akka
  • 为什么在读取字典时要锁定

    我对我正在阅读的一本关于线程的书 C 3 in a Nutshell 中的代码列表感到困惑 在 应用程序服务器中的线程安全 主题中 给出了以下代码作为 UserCache 的示例 static class UserCache static
  • 如何自定义舍入形式

    我的问题可能看起来很简单 但仍然无法得到有效的东西 我需要自定义 Math round 舍入格式或其他格式以使其工作如下 如果数字是 1 6 他应该四舍五入到 1 如果大于或等于 1 7 他应该四舍五入到 2 0 对于所有其他带有 6 的小
  • UseCompressedOops JVM 标志有什么作用以及何时应该使用它?

    HotSpot JVM 标志是什么 XX UseCompressedOops我应该做什么以及什么时候使用它 在 64 位 Java 实例上使用它 与不使用它 时 我会看到什么样的性能和内存使用差异 去年大多数 HotSpot JVM 都默认
  • Joshua Bloch 的构建器设计模式有何改进?

    早在 2007 年 我就读过一篇关于 Joshua Blochs 所采用的 构建器模式 的文章 以及如何修改它以改善构造函数和 setter 的过度使用 特别是当对象具有大量属性 其中大部分属性是可选的 时 本文对此设计模式进行了简要总结
  • Lombok 不适用于 Eclipse Neon

    我下载了lombok jar lombok 1 16 14 jar 并将其放入我的下载中 然后我点击这个 jar 执行正确地识别了我的 MacOS 上的 Eclipse 实例 然后我选择了我想要的实例 Lombok也在pom xml中指定
  • 确定 JavaFX 中是否消耗了事件

    我正在尝试使用 JavaFX 中的事件处理来做一些非滑雪道的事情 我需要能够确定手动触发事件后是否已消耗该事件 在以下示例中 正确接收了合成鼠标事件 但调用 Consumer 不会更新该事件 我对此进行了调试 发现 JavaFX 实际上创建
  • Selenium 单击在 Internet Explorer 11 上不起作用

    我尝试在 Internet Explorer 上单击 selenium 但它不起作用 我努力了element click moveToElement element click build perform javascript没事了 事实上
  • 如何让 Firebase 与 Java 后端配合使用

    首先 如果这个问题过于抽象或不适合本网站 我想表示歉意 我真的不知道还能去哪里问 目前我已经在 iOS 和 Android 上开发了应用程序 他们将所有状态保存在 Firebase 中 因此所有内容都会立即保存到 Firebase 实时数据
  • Java 的“&&”与“&”运算符

    我使用的示例来自 Java Herbert Schildt 的完整参考文献 第 12 版 Java 是 14 他给出了以下 2 个示例 如果阻止 第一个是好的 第二个是错误的 因此发表评论 public class PatternMatch
  • Spring 作为 JNDI 提供者?

    我想使用 Spring 作为 JNDI 提供程序 这意味着我想在 Spring 上下文中配置一个 bean 可以通过 JNDI 访问该 bean 这看起来像这样
  • C#中为线程指定特殊的cpu

    我有 2 个线程 我想告诉其中一个在第一个 cpu 上运行 第二个在第二个 cpu 上运行 例如在具有两个 cpu 的机器中 我怎样才能做到这一点 这是我的代码 UCI UCIMain new UCI Thread UCIThread ne
  • GAE 无法部署到 App Engine

    我正在尝试从 Eclipse 发布 Web 应用程序 我在 GAE 上创建了四个项目 可以通过登录我的帐户并查看控制台来查看它们 我已经改变了appengine web xml到项目的应用程序 ID 如果我将其更改为 GAE 上第一个创建的

随机推荐

  • 如何使用 LINQ 将这些数据组织成我想要的对象?

    我有一个以下类 我试图创建一个包含我查询过的一堆数据的列表 public class Agency public string AgencyName get set public int AgencyID get set public IE
  • Weblogic 12.1.3 PrivilegedActions 类未找到

    我创建了一个简单的项目 调用 jms 队列并放入消息 这里是代码 public class QueueSend Defines the JNDI context factory public final static String JNDI
  • 在 iOS 配置门户上创建 AdHoc 配置文件时出错 [已关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 每当我尝试
  • IE想要从Django下载返回的JSON

    我有一个 Django 站点 其中一个页面正在执行基于 AJAX 的文件上传 使用Valum 的文件上传器 http valums com ajax upload 通过 JSON 返回一些信息 Django 返回 JSON 的方式是 ret
  • Dapper for NET Core:插入表并返回插入行的 id [重复]

    这个问题在这里已经有答案了 我的存储库中有以下方法 到目前为止 我相信返回的 int 只是指示操作是否成功的一个 我希望 int 是成功执行后返回的 id 表的单列 我该如何做到这一点 public async Task
  • 邮件中的证书链错误中的自签名证书

    我尝试编写一个简单的邮件程序 我用了节点邮件程序 and SMTP协议模块 我执行了 但它显示一个错误 例如 邮件中的证书链错误中的自签名证书 问题是什么 var express require express var app expres
  • 在 vscode 中调试 Serverless 时未命中断点

    在 VSCode 中调试基于无服务器的应用程序时 我的断点均未处于活动状态 启动 json configurations console integratedTerminal cwd workspaceRoot name Debug por
  • 如何正确使用 LINQ 和 MySQL? [复制]

    这个问题在这里已经有答案了 可能的重复 LINQ to MySQL 最好的选择是什么 https stackoverflow com questions 1469100 linq to mysql what is the best opti
  • Virtualenv 与 Eclipse (Galileo) [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 有人可以指导让 Eclipse Galileo PyDev 和 Virtualenv 一起工作吗 我专门尝试运行 Pinax 但任何说
  • C++:处理线程本地对象销毁

    我有一个日志系统 它基本上使用线程本地缓冲区来记录 这有助于减少锁定 可以将一堆消息写入线程本地缓冲区并一次性刷新 而且由于它是线程本地的 我们可以避免为每个日志消息分配缓冲区 无论如何 问题是在进程退出期间 我们在访问线程本地缓冲区时看到
  • 如何以不同的增量减去 2 个单独文件的特定行

    https i stack imgur com oYoYz png https i stack imgur com oYoYz png https i stack imgur com AdmuM png https i stack imgu
  • 如何在 MVC 模型中表示一个月的复选框

    我无法理解如何使用 MVC 创建下表 并将其成功绑定到模型 我基本上需要跟踪该月的哪几天需要发生事件 这是我对模型的尝试 EDIT 这不是一个月 而是任意 4 周的周期 public class ScheduleViewModel publ
  • 对术语...进行抽象会导致术语...类型错误

    这是我想证明的 A Type i nat index f nat nat n nat ip n lt i partial index f nat option nat L partial index f index f n Some n V
  • 在 PostgreSQL 中声明“not-null-string”数组类型的列

    使用 PostgreSQL 9 6 我可以创建一个类型为 not null array of string 的列 CREATE TABLE example foo TEXT NOT NULL 但这允许元素为空 即我可以这样做 INSERT
  • 在哪里可以找到有关如何开发(rails 3)助手的文档[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我可能是瞎子 但我真的找不到任何关于如何在 Rails 3 中为您自己的视图编写帮助程序的好文档 我正
  • 像 Android 电视 Leanback 中的 Android 手机一样的垂直列表

    我想创建一个简单的垂直列表 一行中的单列 它只能垂直滚动 不能水平滚动 我如何使用 Leanback 在 Android 电视上实现此目的 有关 ui 要求的更多说明 请参阅下图 我尝试使用 VerticalSupportFragment
  • 搜索未排序的数组

    也可能具有重复元素的未排序数组中的最小和最大比较次数是多少 我知道在未排序的数组中查找任何内容都是 O n 问题 但是 如果数组也包含重复元素 这是真的吗 我所说的重复元素是指在给定数组中多次出现的元素 所以这里的想法是你必须从头到尾遍历数
  • 互斥体是如何实现的?

    对于特定应用程序 某些实现是否比其他实现更好 通过推出自己的产品有什么收入吗 查看描述测试和设置 http en wikipedia org wiki Test and set维基百科上的机器指令 它暗示了如何在机器级别实现原子操作 我可以
  • 使用 PHP 发送文件时在 Internet Explorer 中维护自定义文件扩展名?

    我有一个服务器端 zip 存档 我想将其作为下载传递 我正在使用自定义扩展将这些特定档案与某些客户端软件相关联 例如 CustomArchive bwz Chrome 和 FireFox 可以完美处理此自定义扩展 但 Internet Ex
  • 带Executor和不带Executor的多线程区别

    我试图找出普通多线程和使用执行器的多线程 维护线程池 之间的性能差异 以下是两者的代码示例 没有执行器代码 使用多线程 import java lang management ManagementFactory import java la