强制多个线程在多个 CPU 可用时使用它们

2024-01-12

我正在编写一个 Java 程序,由于其工作性质,该程序使用大量 CPU。然而,其中很多可以并行运行,并且我已经使我的程序成为多线程的。当我运行它时,它似乎只使用一个 CPU,直到它需要更多的 CPU,然后才使用另一个 CPU - 我可以在 Java 中做些什么来强制不同的线程在不同的内核/CPU 上运行吗?


Java 中的多线程有两种基本方法。您使用这些方法创建的每个逻辑任务都应该在需要且可用时在新的核心上运行。

方法一:定义一个 Runnable 或 Thread 对象(可以在构造函数中接受 Runnable)并使用 Thread.start() 方法启动它运行。它将在操作系统提供的任何核心上执行——通常是负载较少的核心。

教程:定义和启动线程 http://java.sun.com/docs/books/tutorial/essential/concurrency/runthread.html

方法二:定义实现 Runnable(如果它们不返回值)或 Callable(如果它们返回值)接口的对象,其中包含您的处理代码。将这些作为任务从 java.util.concurrent 包传递给 ExecutorService。 java.util.concurrent.Executors 类有很多方法来创建标准的、有用的 ExecutorServices。Link http://java.sun.com/docs/books/tutorial/essential/concurrency/exinter.html执行者教程。

从个人经验来看,固定和缓存线程池的执行器非常好,尽管您需要调整线程计数。 Runtime.getRuntime().availableProcessors() 可在运行时用于计算可用内核数。当应用程序完成时,您需要关闭线程池,否则应用程序将不会退出,因为 ThreadPool 线程保持运行。

获得良好的多核性能有时很棘手,并且充满陷阱:

  • 运行时磁盘 I/O 会减慢很多 平行线。一次只能有一个线程进行磁盘读/写。
  • 对象同步为多线程操作提供了安全性,但会减慢工作速度。
  • 如果任务太多 琐碎(小工作位,执行 快)管理它们的开销 ExecutorService 的成本超过 您可以从多个核心中获益。
  • 创建新的 Thread 对象很慢。如果可能,ExecutorServices 将尝试重用现有线程。
  • 当多个线程处理某件事时,可能会发生各种疯狂的事情。保持系统简单,并尝试使任务在逻辑上清晰且非交互。

另一个问题是:控制工作很难!一种好的做法是使用一个管理器线程来创建和提交任务,然后使用几个带有工作队列的工作线程(使用 ExecutorService)。

我在这里只是触及要点——多线程编程被许多专家认为是最难的编程主题之一。它不直观、复杂,而且抽象性往往很弱。


编辑——使用 ExecutorService 的示例:

public class TaskThreader {
    class DoStuff implements Callable {
       Object in;
       public Object call(){
         in = doStep1(in);
         in = doStep2(in);
         in = doStep3(in); 
         return in;
       }
       public DoStuff(Object input){
          in = input;
       }
    }

    public abstract Object doStep1(Object input);    
    public abstract Object doStep2(Object input);    
    public abstract Object doStep3(Object input);    

    public static void main(String[] args) throws Exception {
        ExecutorService exec = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        ArrayList<Callable> tasks = new ArrayList<Callable>();
        for(Object input : inputs){
           tasks.add(new DoStuff(input));
        }
        List<Future> results = exec.invokeAll(tasks);
        exec.shutdown();
        for(Future f : results) {
           write(f.get());
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

强制多个线程在多个 CPU 可用时使用它们 的相关文章

随机推荐

  • 在 CSS 中选择相邻的和之前的兄弟姐妹

    比如说我有以下 HTML ul li a href a A a li li a href b B a li li class myclass a href c C a li li a href d D a li li a href e E
  • Java String.split() 有时会给出空白字符串

    我正在制作一个基于文本的骰子滚筒 它接受像 2d10 5 这样的字符串 并返回一个字符串作为掷骰的结果 我的问题出现在分词器中 它将字符串分割成有用的部分 以便我解析成信息 String tokens message split dk 这产
  • SQLAlchemy 验证 SSL 连接

    我想验证 SQLAlchemy 在使用时设置的 SSL 连接create engine连接到 PostgreSQL 数据库 例如 如果我有以下 Python 3 代码 from sqlalchemy import create engine
  • 无法解析方法startActivity()

    我是 Android 开发新手 在更改活动时遇到了一些问题 我正在尝试从方法内更改活动 但收到错误cannot resolve method startActivity并在参数结束时出现错误Cannot resolve constructo
  • VueJS webpack PWA 资产图标 manifest.json

    我配置了我的 PWAmanifest json in vue config js 如下所示 如何配置 PWA 图标以引用内部的图像assets folder module exports pwa manifestOptions name p
  • 从 Pandas 数据框中删除“主导”行(所有值都低于任何其他行的值的行)

    编辑 为了清楚起见更改了示例 df 我有一个数据框 类似于下面给出的数据框 除了真实的数据框有几千行和列 并且值是浮点数 df pd DataFrame 6 5 4 3 8 6 5 4 3 6 1 1 3 9 5 0 1 2 7 4 2 0
  • WSL2 Docker Linux 卷权限问题

    我正在使用 Docker 构建 Jekyll 网站 我正在使用 Windows 10 和 WSL2 以及 Debian 如果我在 Windows 环境中从 Powershell 运行以下命令 docker run rm label jeky
  • 如何使用 SIGSEGV 信号处理程序调试程序

    我正在为应用程序编写一个插件 有时会抛出 SIGSEGV 然而 应用程序捕获信号 SIGSEGV 换句话说 该插件是一个动态库 该错误发生在我的插件和动态库中 但应用程序处理 sSIGSEGV 并正常退出 因此 对我来说调试并获取所有堆栈帧
  • SQL Server 中的 IGNORE_DUP_KEY 选项

    我在 MSDN 和 Google 上做了很多搜索 但看起来像描述IGNORE DUP KEY选择非常有限 我的困惑 Is IGNORE DUP KEY选项 一个列的选项 为了一张桌子 对于几列 对于索引 使索引唯一 If set IGNOR
  • Android - 如何在录音时添加增益控制

    我为录音机应用程序工作 想添加增益控制 但我不知道该怎么做 我可以访问音频缓冲区 但我不知道如何使声音更大或更慢 我看到另一个应用程序有一个搜索栏 用于从特定范围内选择分贝 aRecorder read buffer 0 buffer le
  • 如何获取套接字的主机名?

    当我从连接的套接字接收到某个事件时 我必须发送一个带有我的主机名和端口作为参数的请求 我希望能够从套接字对象检索此信息 不幸的是 关于这方面的文档很少 我似乎无法找出这是否以及如何可能 那么 是否可以在 Socket io 中执行类似的操作
  • 如何在 中显示文件路径?

    I tried
  • Get-InstalledModule 和 Get-Module -ListAvailable 之间有什么区别?

    据我所知 他们做了同样的事情 那么使用其中一种而不是另一种的原因是什么 抱歉 所以问题规则引擎 不知道还能说什么 Get InstalledModule是其一部分PowerShellGet并将使用列出已安装的模块Install Module
  • Excel IFERROR 的 R 等效项是什么?

    我正在尝试将 IFERROR 条件放入 R 中 就像 Excel IFERROR 函数一样 我正在构建一个随机森林模型 为了进行微调 我使用tuneRF函数 它有助于给出最佳的 mtry 参数 Selecting Optimal MTRY
  • 将 Python 脚本作为 Windows 后台进程运行 [重复]

    这个问题在这里已经有答案了 我一直在尝试编写一个从串行端口读取数据的Python脚本 它在命令行中运行良好 但我需要它作为后台进程运行 而无需任何命令行界面 该脚本有一个 while 循环 它从串行端口读取下一个数据字节并相应地模拟按键 为
  • 使用 ANSI 转义序列获取终端大小?

    在研究这个问题时 在评论中我发现有人提到 ANSI 转义码来获取终端大小 由于我将使用 ANSI 转义序列 我认为这将是一种比获取终端大小更优雅的方法ioctl or getenv 这是一篇关于ioctl https stackoverfl
  • 如何使用 Tailwind 修改 svg 图标颜色

    我正在使用 TailwindCSS 并且想要更改 svg 的颜色 没有 Tailwind 这个问题之前已经被问过here https stackoverflow com questions 22252472 how to change th
  • 来自 AlertDialog 的 findViewById(使用自定义布局)- NullPointerException

    我正在尝试从 AlertDialog 中的 EditTexts 中获取文本 该对话框的创建方式如下所示 问题是 我无法检索文本视图 我得到的只是一个空值 有任何想法吗 final EditText editFirstname EditTex
  • Cassandra 要求允许过滤,即使列是聚集键

    对 Cassandra 非常陌生 如果问题很简单 我们深表歉意 我创建了一个表 create table ApiLog LogId uuid DateCreated timestamp ClientIpAddress varchar pri
  • 强制多个线程在多个 CPU 可用时使用它们

    我正在编写一个 Java 程序 由于其工作性质 该程序使用大量 CPU 然而 其中很多可以并行运行 并且我已经使我的程序成为多线程的 当我运行它时 它似乎只使用一个 CPU 直到它需要更多的 CPU 然后才使用另一个 CPU 我可以在 Ja