Tôi đang mô phỏng một hệ thống ngân hàng mà tôi có 100.000 giao dịch để chạy. Mỗi loại giao dịch thực hiện runnable và tôi có nhiều loại giao dịch khác nhau có thể xảy ra.Chạy 100.000 quy trình đồng thời
transactions
là một loạt các Runnables.
Lý tưởng nhất, các mã sau đây sẽ giải quyết vấn đề của tôi:
for (Transaction transaction : transactions) {
new Thread(transaction).start();
}
Tuy nhiên, rõ ràng là một java.lang.OutOfMemoryError: unable to create new native thread
là ràng buộc để xảy ra khi cố gắng để bắt đầu 100,000 chủ đề.
Vì vậy, tiếp theo, tôi đã thử triển khai ExecutorService để tạo một nhóm luồng để quản lý 100.000 lần chạy của tôi.
ExecutorService service;
int cpus = Runtime.getRuntime().availableProcessors();
// cpus == 8 in my case
service = Executors.newFixedThreadPool(cpus);
for (Transaction transaction : transactions) {
service.execute(transaction);
}
Khi thử phương pháp này, các quy trình dài "hog" JVM. Ví dụ: một loại giao dịch mất 30 - 60 giây để thực thi. Khi lược tả ứng dụng, không có chủ đề nào khác được phép chạy trong khi giao dịch dài diễn ra.
Trong trường hợp này, chủ đề 6 không cho phép bất kỳ chủ đề khác để chạy cho đến khi chế biến của nó đã được hoàn tất.
Vì vậy, câu hỏi của tôi là: Làm thế nào tôi có thể chạy 100.000 giao dịch nhanh nhất có thể mà không gặp phải vấn đề về bộ nhớ? Nếu ExecutorService là câu trả lời, thì làm thế nào tôi có thể dừng các giao dịch rất dài từ việc hogging JVM và cho phép các giao dịch khác chạy đồng thời?
EDIT:
Tôi buộc một số loại giao dịch xảy ra trong vòng 30 - 60 giây trên mục đích để đảm bảo rằng chương trình ren của tôi đang làm việc một cách chính xác. Mỗi giao dịch sẽ khóa trên một tài khoản và có 10 tài khoản. Đây là phương pháp của tôi mà heo JVM: (gọi bằng 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;
}
}
}
}
Mỗi lần giao dịch này được chạy, chỉ có một tài khoản sẽ bị khóa, khiến 9 người khác mà nên có sẵn để xử lý. Làm thế nào để JVM không xử lý thêm bất kỳ chủ đề nào, và thay vào đó bị treo cho đến khi giao dịch dài này kết thúc?
Đây là một liên kết đến một phiên bản rút gọn của dự án để chứng minh vấn đề: project
Bạn không nên tạo cùng một số lượng luồng làm giao dịch. Thay vào đó tạo ra số lượng cố định của các chủ đề như 100 và cho phép họ làm việc trên 100000 giao dịch bằng cách sử dụng ExecutorsService – virendrao
Bạn có thể hiển thị [một ví dụ hoàn chỉnh] (http://stackoverflow.com/help/mcve) sao chép hành vi đó không? – assylias
@assylias đã thêm – Feek