簡體   English   中英

如何使此代碼更並發?

[英]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通道。 但這有一些缺點:

  1. 線程由OS(或小型幫助程序庫)管理。 它們需要內存,並且每次切換線程時,CPU都必須保存其狀態並刷新其緩存。
  2. 如果線程僅執行少量工作,則線程切換可能比執行工作更昂貴。
  3. 使用線程時,會遇到所有常見的線程同步問題。
  4. 沒有簡單的方法來確保您擁有正確數量的線程。 如果線程太少,則無法最佳地使用IO通道。 如果線程太多,則通道將無法最佳使用,因為線程將爭奪它的訪問權限。 在這兩種情況下,您都無法在開始測試后更改此設置。 該系統無法適應需求。

對於這樣的任務,像Akka這樣的框架更適合,因為它避免了所有這些問題,並且比線程使用起來更簡單。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM