2012-11-27 88 views
0

我運行的核心java服務器所做的一件事就是處理兩種類型的任務(T1和T2)。最初這些任務正在從相同的隊列和線程處理。有時隊列包含大約1000個T1任務,這會導致下一個T2任務的延遲。所以我決定改變架構並在一個單獨的線程和獨立的隊列中處理每個任務。但看起來JVM仍然會在切換到其他線程並處理T2任務之前處理〜1000個T1任務(大約0.6秒)。由java線程處理的多個任務延遲了另一個java線程

我正在運行「紅帽企業Linux服務器版本6.1(聖地亞哥)」的四核機器上運行。

我假設兩個線程正在同一個CPU上運行。

有什麼方法可以讓操作系統或JVM更頻繁地切換嗎? 還有一種方法可以查看哪個處理器正在處理哪個線程?

我已驗證兩個線程正在使用調試器作爲單獨的線程運行。使用

this.executor.Executors.newSingleThreadExecutor(); 

創建

一個線程和任務使用

executor.submit(new Task2(..)); 

另一個線程提交的是管理它自己的隊列中的遺留代碼:

private final BlockingQueue<...> workQueue = new LinkedBlockingQueue<...>(); 
.... 
public void submit(Task1 task) { 
    workQueue.add(task); 
} 

.... 

    public void run() { 
    while (alive){ 
     try{ 
      Task1 task = workQueue.take(); 
          processwork(task); 
        } 
.... 
+5

也許你的代碼有問題,你沒有發佈? –

+0

你是否100%肯定這兩個任務在不同的線程中運行?你如何確定T2只在所有1000個T1被處理後才啓動? – assylias

+0

你是否正在調用runnable而不是在線程中保存Runnable並調用start?只是一個預感:-)請張貼您的代碼 –

回答

0

經過分析,我發現的延遲是由另一個線程提前(在提交之前)引起這兩個任務共享。

0

我同意評論表明可能存在防止並行性的程序問題。但是,如果情況並非如此,則可以採取兩種方法來建議更多的切換:

  1. 降低T1線程的優先級。
  2. 在每個T1任務結束時在T1線程中插入一個yield調用。
+3

注意Java線程的優先級,由於JVM嘗試映射到OS線程優先級的方式,它們幾乎沒有用處。 – lynks

0

從當前的描述,這是正確的答案是:你需要調用thread.start()而非thread.run()

如果沒有,你需要張貼代碼:)