2011-03-08 30 views
6

Tôi đã có một ứng dụng đa luồng. Khi sử dụng Thread.start() để bắt đầu thủ công mỗi luồng đồng thời sử dụng chính xác 25% CPU (hoặc chính xác một lõi - đây là trên một máy lõi tứ). Vì vậy, nếu tôi chạy hai chủ đề sử dụng CPU là chính xác 50%.Java: ExecutorService kém hiệu quả hơn so với thực thi chuỗi thủ công?

Khi sử dụng ExecutorService để chạy luồng tuy nhiên, dường như có một tài nguyên CPU tiêu thụ "ma"! Một Chủ đề sử dụng 50% thay vì 25%, hai chuỗi sử dụng 75%, v.v.

Đây có phải là một số loại cửa sổ tác vụ quản lý tác phẩm không?

Excutor mã dịch vụ là

ExecutorService executor = Executors.newFixedThreadPool(threadAmount); 

for (int i = 1; i < 50; i++) { 
    Runnable worker = new ActualThread(i); 
    executor.execute(worker); 
} 
executor.shutdown(); 
while (!executor.isTerminated()) { 

} 
System.out.println("Finished all threads"); 

và Thread.start mã() là:

ActualThread one= new ActualThread(2,3); 
ActualThread two= new ActualThread(3,4); 
... 

Thread threadOne = new Thread(one); 
Thread threadTtwo = new Thread(two); 
... 

threadOne.start(); 
threadTwo.start(); 
... 
+1

Mã ở đâu để chờ các chuỗi kết thúc trong ví dụ thứ hai? –

Trả lời

16

Dưới đây là vấn đề của bạn:

while (!executor.isTerminated()) { 

} 

phương pháp "chính" của bạn đang quay các CPU không làm gì cả. Thay vào đó, hãy sử dụng invokeAll() và chuỗi của bạn sẽ bị chặn mà không phải đợi quá lâu.

final ExecutorService executor = Executors.newFixedThreadPool(threadAmount); 
final List<Callable<Object>> tasks = new ArrayList<Callable<Object>>(); 

for (int i = 1; i < 50; i++) { 
    tasks.add(Executors.callable(new ActualThread(i))); 
} 
executor.invokeAll(tasks); 
executor.shutdown(); // not really necessary if the executor goes out of scope. 
System.out.println("Finished all threads"); 

Kể từ invokeAll() muốn có một bộ sưu tập các Callable, lưu ý việc sử dụng các phương pháp helper Executors.callable(). Bạn thực sự có thể sử dụng điều này để có được một bộ sưu tập của Future s cho các tác vụ là tốt, đó là hữu ích nếu các nhiệm vụ thực sự sản xuất một cái gì đó bạn muốn là đầu ra.

+1

+1, thay đổi nhỏ hơn một chút sẽ là sử dụng 'awaitTermination'. –

+0

@Mark, vâng, nhưng tại sao các nhào lộn thủ công khi 'invokeAll()' có sẵn cho bạn? Mô hình này khuyến khích tái sử dụng của người thực thi, mà thường là một điều tốt ... trong mọi trường hợp, hoặc là hoạt động. – andersoj

Các vấn đề liên quan