[英]How can I make this code more concurrent?
我有一段類似於以下內容的代碼:
final int THREADS = 11;
BlockingQueue<Future<Long>> futureQueue = new ArrayBlockingQueue<Future<Long>>(THREADS);
for (int i = 0; i < end; i++, count++) {
futureQueue.put(executor.submit(MyRunnable));
}
//Use queued results
我如何重構它以使其並發 ? 我在這里有什么微妙之處嗎?
更新:
每個Runnable都應該向服務器發送大量HTTP請求以進行壓力測試。
我會用
static final int THREADS = Runnable.getRuntime().availableProcesses();
ExecutorService service = Executors.newFixedThreadPool(THREADS);
List<Future<Long>> futureQueue = new ArrayList<Future<Long>>(end);
for (int i = 0; i < end; i++)
futureQueue.add(executor.submit(new MyRunnable()));
您正在使用有界隊列,如果end > THREADS
,它將停止。
每個Runnable都應該向服務器發送大量HTTP請求以進行壓力測試。
在這種情況下,我將使用以下代碼,因為您的代碼是IO而不是CPU。
ExecutorService service = Executors.newCachedThreadPool();
如果擁有1000個以上的線程,您可能會從使用NIO中受益,但這只會使您的負載測試器更高效,但會使代碼更加復雜。 (如果你覺得這是很難的,編寫有效的,正確的選擇代碼更難 )
在多台機器上運行測試儀將帶來更多不同。
使用線程不適用於您的情況。 當您有大量的CPU工作時,線程池會很好地工作。 在您的情況下,您有一個IO密集型工作-它不受您擁有的CPU數量的限制,而是受您可以發送的網絡數據包數量的限制。
在這種情況下,NIO中的課程是您的朋友。 創建數百個連接,並使用NIO選擇器查看准備接收更多數據的連接器 。
使用這種方法,您根本不需要線程。 一個CPU內核足以滿足GBit以太網連接(〜100MB / s)的需求。
[編輯]當然,您可以創建數百個線程來嘗試填充IO通道。 但這有一些缺點:
對於這樣的任務,像Akka這樣的框架更適合,因為它避免了所有這些問題,並且比線程使用起來更簡單。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.