2011-04-11 46 views
0

現在我決定處理髮送給服務器的請求對象的最佳方式。換句話說,我的應用程序中有跟蹤請求對象,用於展示和點擊跟蹤等內容。具有非常低的有效載荷的簡單請求。在我的應用程序中有一些地方需要跟蹤的對象並排顯示(最多需要跟蹤三個併發對象),因此每次所述對象都可見時,我必須創建一個跟蹤請求對象爲他們每個人。Java POJO:處理請求對象隊列到服務器的策略

現在我已經知道我可以很容易地創建一個單例隊列線程,將這些對象添加到一個向量中,我的線程或者在主循環中處理它們,或者在隊列中調用等待直到我們有要處理的對象。雖然這聽起來像是一個明確的解決方案,但是隊列可以累積到幾十個,這有時很麻煩,因爲它爲每個請求建立一個連接,因此它不會同時運行。

我想到的是創建一個線程池,它允許我通過信號量創建兩個併發連接,並處理將包含我的跟蹤事件請求的線程對象。換句話說,我想創建一個函數來創建一個新的線程Object並將其添加到Vector中,其中線程池將遍歷這組線程並一次處理它們兩個。我知道我可以創建一個可以添加如下對象的函數:

public boolean addThread(Runnable r){ 
synchronized(_queue){ 
    while(!dead){ 
     _queue.addElement(r); 
     //TODO: How would I notify my thread pool object to iterate through the list to process the queue? Do I call notify on the queue object, but that would only work on a thread right?? 
     return true 
    } 
    return false; 
} 

我想知道的是線程本身將如何執行。我怎樣才能編寫一個函數在將線程添加到列表後執行線程池?此外,由於信號量將在第二次連接後阻塞,是否會鎖定我的應用程序,直到出現空插槽,或者它是否會鎖定線程池對象,同時在列表中循環?

與往常一樣,由於我針對的是J2ME/Blackberry環境,因此只會接受1.5之前的答案,所以沒有泛型或Concurrent包中的任何類。

編輯:所以我認爲這是它應該是什麼樣子或多或少:

class MyThreadPool extends Thread{ 

    private final Vector _queue = new Vector(); 
    private CappedSemaphore _sem; 
    public MyWaitingThread(){ 
     _sem = new CappedSemaphore(2); 
     this.start(); 
    } 
    public void run(){ 
    while(!dead){ 
     Runnable r = null; 
     synchronized(_queue){ 
      if(_queue.isEmpty()){ 
      _queue.wait(); 
      } else { 
      r = _queue.elementAt(0); 
      _queue.removeElement(0); 
      } 
     } 
     if(r != null){ 
      _sem.take(); 
      r.run(); 
      _sem.release(); 
     } 
    } 
} 
public boolean addThread(Runnable r){ 
    synchronized(_queue){ 
    if(!dead){ 
    _queue.addElement(r); 
    _queue.notifyAll(); 
    return true 
    } 
    return false; 
} 
} 
+2

您不應該那麼快地折扣Java 5併發包。在Java 5中沒有什麼能夠啓用它的神奇功能,其中大部分都是由Java 1.4中的Doug Lea完成的,它只是在Java 5中進行了標準化。http://backport-jsr166.sourceforge.net/index.php是一個迴流。 – 2011-04-12 00:43:57

+0

由於Semaphore的實現實現了Serializable(MIDP/CLDC中不存在的東西),所以我不能簡單地導入類,因此我打算實現POJO解決方案,這是可以實現的在原始的和裸骨頭的物體上。 – 2011-04-12 04:16:17

+0

這一切都看起來不錯,有一個想法。如果你確保始終有兩個線程啓動,你不需要信號量。您將併發限制在線程局部性,因此您不必擔心另一個同步原語。否則你應該有什麼工作。 – 2011-04-12 13:34:28

回答

-1

你想這樣做,在上線側什麼對隊列中的每個線程等待。例如

class MyWaitingThread extends Thread{ 

    private final Queue _queue; 
    public MyWaitingThread (Queue _queue){ 
     this._queue = _queue; 
    } 
    public void run(){ 
     while(true){ 
     Runnable r = null; 
     synchronized(_queue){ 
      if(_queue.isEmpty()) 
       _queue.wait(); 
      else 
       r = queue.pop(); 
     } 
     if(r != null) r.run(); 
     } 
    } 
} 

而在你的其他邏輯它看起來像:

public void addThread(Runnable r){ 
    if(!dead){ 
     synchronized(_queue){ 
     _queue.addElement(r); 
     _queue.notifyAll(); 
     } 
    } 
} 

_queue.notifyAll將喚醒等待的_queue實例的所有線程。另外,請注意,我將while(!dead)移到了同步塊之外,並將其更改爲if(!dead)。我可以想象保持它原來不會像你所希望的那樣工作的方式。

+0

我想我忘記編輯函數來返回一個布爾值,這樣它就可以跳過while循環,因爲這是Sun爲J2ME線程教程中的簡單隊列示例所做的工作。我現在去解決這個問題。另外,我不能使用Queue對象,因爲它不適用於J2ME,但我明白你的意思。我必須調用elementAt然後removeElement,以便從我的Vector隊列中抽取出我的對象。 – 2011-04-12 04:18:04