我正在模拟一个银行系统,其中要运行 100,000 笔交易。每种类型的事务都实现了可运行的,并且我有各种类型的事务可以发生。
transactions
是一个 Runnable 数组。
理想情况下,以下代码可以解决我的问题:
for (Transaction transaction : transactions) {
new Thread(transaction).start();
}
但是,显然 java.lang.OutOfMemoryError: unable to create new native thread
在尝试启动 100,000 个线程时必然会发生。
接下来我尝试实现一个 ExecutorService 来创建一个线程池来管理我的 100,000 个可运行对象。
ExecutorService service;
int cpus = Runtime.getRuntime().availableProcessors();
// cpus == 8 in my case
service = Executors.newFixedThreadPool(cpus);
for (Transaction transaction : transactions) {
service.execute(transaction);
}
尝试这种方法时,长进程会“占用”JVM。例如,一种类型的交易需要 30 - 60 秒才能执行。在分析应用程序时,不允许其他线程在长事务发生时运行。
在这种情况下,线程 6 在其处理完成之前不允许任何其他线程运行。
所以我的问题是:如何在不遇到内存问题的情况下尽可能快地运行 100,000 个事务?如果 ExecutorService 是答案,那么我如何才能阻止非常长的事务占用 JVM 并允许其他事务并发运行?
编辑:
我故意强制某些类型的事务发生 30 - 60 秒,以确保我的线程程序正常工作。每笔交易锁定一个账户,共有 10 个账户。这是我占用 JVM 的方法:(由 run()
调用)
public void makeTransaction() {
synchronized(account) {
long timeStarted = System.nanoTime();
long timeToEnd = timeStarted + nanos;
this.view = new BatchView(transactionNumber, account.getId());
this.displayView();
while(true) {
if(System.nanoTime() % 1000000000 == 0) {
System.out.println("batch | " + account.getId());
}
if(System.nanoTime() >= timeToEnd) {
break;
}
}
}
}
每次运行此事务时,只有一个帐户被锁定,剩下 9 个帐户应可用于处理。 为什么 JVM 不再处理任何线程,而是挂起直到这个长事务完成?
这里是项目的缩小版本的链接,用于演示问题:project
最佳答案
When profiling the application, no other threads are being allowed to run while the long transaction takes place.
很可能,此任务正在使用单线程资源。即 ti 的编写方式会阻止并发使用。
How can I run 100,000 transactions as fast as possible without running into memory problems?
如果事务受 CPU 限制,您应该有一个与您拥有的 CPU 数量大小相同的池。
如果事务依赖于数据库,您应该考虑对它们进行批处理以更有效地利用数据库。
If ExecutorService is the answer, then how can I stop very long transactions from hogging the JVM and allow other transactions to run concurrently?
使交易更短。如果您有一个运行时间超过几毫秒的任务,您应该弄清楚为什么要花这么长时间。我将首先查看网络/IO 必须如何使用和分析任务。大多数交易(如果您有大量交易)应该在 0.01 秒左右或更理想。
您应该仔细考虑如何使用共享资源。如果您的任务过多地使用相同的资源,您可能会发现多线程并不快,甚至更慢。
关于java - 并发运行 100,000 个进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29160702/