- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有 N 个 long,它们是 ID。对于每个 ID,我都需要执行一个 Runnable(即,我不关心返回值)并等待所有这些都完成。每个 Runnable 可能需要几秒到几分钟,并行运行大约 100 个线程是安全的。
在我们当前的解决方案中,我们使用 Executors.newFixedThreadPool(),为每个 ID 调用 submit(),然后对每个返回的 Future 调用 get()。
代码运行良好并且非常简单,因为我不必处理线程、复杂的等待逻辑等。它有一个缺点:内存占用。
所有仍在排队的 Runnable 消耗内存(比 long 需要的多 8 个字节:这些是我的具有某些内部状态的 Java 类),并且所有 N 个 Future 实例也消耗内存(这些是具有状态也是如此,我只用它来等待,但我不需要实际结果)。我查看了堆转储,我估计 N=1000 万占用了略多于 1 GiB 的内存。一个数组中的 1000 万个 long 只会消耗 76 MiB。
有没有办法只将 ID 保存在内存中来解决这个问题,最好不要求助于低级并发编程?
最佳答案
这是我通常使用生产者/消费者模式和协调两者的 BlockingQueue 做的事情,或者,如果我手头有项目,则使用 Akka actor。
但我认为我会根据 Java 的 Stream 行为提出一些不同的建议。
直觉是,流的惰性执行将用于限制工作单元、 future 及其结果的创建。
public static void main(String[] args) {
// So we have a list of ids, I stream it
// (note : if we have an iterator, you could group it by a batch of, say 100,
// and then flat map each batch)
LongStream ids = LongStream.range(0, 10_000_000L);
// This is were the actual tasks will be dispatched
ExecutorService executor = Executors.newFixedThreadPool(4);
// For each id to compute, create a runnable, which I call "WorkUnit"
Optional<Exception> error = ids.mapToObj(WorkUnit::new)
// create a parralel stream
// this allows the stream engine to launch the next instructions concurrently
.parallel()
// We dispatch ("parallely") the work units to a thread and have them execute
.map(workUnit -> CompletableFuture.runAsync(workUnit, executor))
// And then we wait for the unit of work to complete
.map(future -> {
try {
future.get();
} catch (Exception e) {
// we do care about exceptions
return e;
} finally {
System.out.println("Done with a work unit ");
}
// we do not care for the result
return null;
})
// Keep exceptions on the stream
.filter(Objects::nonNull)
// Stop as soon as one is found
.findFirst();
executor.shutdown();
System.out.println(error.isPresent());
}
老实说,我不确定规范是否保证了这种行为,但根据我的经验,它是有效的。每个并行“chunck”获取一些 id,将其提供给管道(映射到工作单元,分派(dispatch)到线程池,等待结果,过滤异常),这意味着很快达到平衡平衡 Activity 工作单元的数量与 executor
的数量。
如果要微调并行“ block ”的数量,应该在此处跟进:Custom thread pool in Java 8 parallel stream
关于java - 以较小的内存占用量执行数百万次 Runnable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54513866/
是否可以告诉hive某个表“很小”,即应将其复制到所有节点并在RAM中进行操作? 最佳答案 尝试以下提示: /*+ MAPJOIN(small_table) */ UPDATE 顺便说一句,还有其他
给定的是一个大(但不是巨大)的字符串数组(数量为 1000-5000 个单个字符串)。我想对这些字符串执行一些计算和其他操作。因为在处理那个大数组时它总是停止工作,所以我重写了我的函数以递归地获取较小
当我在大小为 (640,480) 的 JFrame 中添加 JPanel 时,JPanel 的大小为 (638449)。我需要 JPanel 与 JFrame 完全匹配! 我发现的一个临时解决方法是将
我目前正在尝试响应设计。我需要在父 div 变小的同时保持图像居中。 见图片说明: 我不想用它作为背景。下面的代码会一直把它放在div框的左上角 #img_wrap {
当我必须捕获生成器中可能发生的异常时,如何使 try block 尽可能小? 典型的情况是这样的: for i in g(): process(i) 如果 g() 可以引发我需要捕获的异常,第一种
目前尝试让 Accordion 项目在 Bootstrap 中工作一切都很好,直到我尝试关闭所有 Accordion 菜单。突然之间,标题比未折叠时小得多。 当一个打开时 当全部关闭时 我正在使用指南
目前尝试让 Accordion 项目在 Bootstrap 中工作一切都很好,直到我尝试关闭所有 Accordion 菜单。突然之间,标题比未折叠时小得多。 当一个打开时 当全部关闭时 我正在使用指南
一个应用程序托管一个具有三个接口(interface)的 Web 服务,用于三个单独且独立的操作,所有这些操作都在应用程序的不同组件中实现,彼此独立,例如在不同的包等中,所以他们对彼此了解不多,只共享
我正在尝试使用 border-radius 属性设计一个主要内容容器具有圆 Angular 的网站。但是,我保持侧边栏和顶部导航栏固定,因此当用户向上或向下滚动时它们不会移动。它类似于在 Google
我正在构建我网站的响应式版本。 虽然我很高兴大多数 float 的 div 被迫在屏幕下方,但有一些 div 我需要保持彼此相邻,即使屏幕区域小于这些 div 的总宽度。在这种情况下,我想按比例缩小它
我正在为我的元素使用 Twitter Bootstraps 网格。我有以下 HTML: Some text Some text
我有一个小宽度的 div 并且可以看到溢出。我有一个更大的表,里面只有一个单元格和一个文本: A small text with spaces...
我有一个设计得很好的架构,其中 Controller 转到访问与数据库通信的存储库的服务。 因此, Controller 中的逻辑保持在最低限度,但我仍然有非常微妙的代码片段来执行一些任务,例如 验证
我在一个布局中有两个 View 。我将分别称它们为 View A 和 View B。 ┌──────┐ │┌─┐┌─┐│ ││A││B││ │└─┘└─┘│ └──────┘ 父布局(包括View A
整个页面的父元素是一个居中的 div,最大宽度限制为 960px。页面上的所有其他元素都是该父 div 的子元素。简化结构如下: 虽然父 div 的宽度不应超过 960px,但我
我应该链接到完整的 jQuery UI -还是-提供精简的自定义副本? 来自 Google 等 CDN 的完整 jQuery-UI 与提供定制的最小版本之间存在非常显着的大小差异。此外,还可以将 jQ
我正在尝试制作一条图像拇指的“线”,它在鼠标移动时滚动。我让它工作了,但我现在的问题是我想在侧面做一个“填充”,这样我就不必将鼠标一直拉到侧面才能看到第一个/最后一个拇指。但我真的无法让它工作:/ 这
我是一名优秀的程序员,十分优秀!