2013-07-17 52 views
1

我的WebApplication中有下面這段代碼,基本上是這樣的,只要用戶登錄到應用程序中。我該如何在此任務中只運行一次

  1. addSymbols方法將在用戶登錄操作期間被調用。
  2. 由於上述原因,PriorityBlockingQueue被觸發
  3. PriorityBlockingQueue將該符號添加到HashSet中,然後迭代該符號以在該新添加的符號上運行特定任務。

我在這裏面臨的問題是,作爲HashSet一部分的while循環一次又一次地執行相同的任務,因爲它處於線程的一個真正的條件內。

我粘貼示例輸出以瞭解與其相關的上下文。

Symbol From priorityBlocking SymbolTest 
Symbol From allSymbolsSet SymbolTest 
Symbol From allSymbolsSet SymbolTest 
Symbol From allSymbolsSet SymbolTest 
Symbol From allSymbolsSet SymbolTest 
Symbol From allSymbolsSet SymbolTest 
Symbol From allSymbolsSet SymbolTest 
Symbol From allSymbolsSet SymbolTest 
Symbol From allSymbolsSet SymbolTest 
Symbol From allSymbolsSet SymbolTest 
Symbol From allSymbolsSet SymbolTest 

這是我的代碼,它做了上述說明。

package com; 
import java.util.HashSet; 
import java.util.Iterator; 
import java.util.Set; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.PriorityBlockingQueue; 

public class TaskerThread extends Thread { 
    private PriorityBlockingQueue<String> priorityBlocking = new PriorityBlockingQueue<String>(); 
    private Set<String> allSymbolsSet = new HashSet<String>(); 
    ExecutorService es = Executors.newFixedThreadPool(2); 

    public void addSymbols(String str) { 
     if (str != null) { 
      priorityBlocking.add(str); 
     } 
    } 

    public void run() { 
     while (true) { 
      try { 
       while (priorityBlocking.peek() != null) { 
        String symbol = priorityBlocking.poll(); 
        allSymbolsSet.add(symbol); 
        try { 
         System.out.println("Symbol From priorityBlocking" +" "+ symbol); 
        } catch (Exception e) { 
          e.printStackTrace(); 
        } 
       } 
       Iterator<String> ite = allSymbolsSet.iterator(); 
       while (ite.hasNext()) { 
        String symbol = ite.next(); 
        if (symbol != null && symbol.trim().length() > 0) { 
         try { 
          System.out.println("Symbol From allSymbolsSet"+" "+symbol); 
         } catch (Exception e) { 
          e.printStackTrace(); 
         } 
        } 
       } 
       Thread.sleep(2000); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
    public static void main(String args[]) { 
     try { 
      TaskerThread qT = new TaskerThread(); 
      qT.start(); 
      qT.addSymbols("SymbolTest"); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

請讓我知道是否有任何方法可以讓Iterator任務只運行一次。

+0

我不能保持迭代部分代碼,而不是真正的條件,因爲如果我這樣做,我將錯過任何要執行的任務,如果有任何新用戶登錄。 – Kiran

+0

不確定它是否解決了任何問題,但您可能想使用['take'](http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html#take %28%29)或['poll(long,TimeUnit)'](http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html#poll%28long,% 20java.util.concurrent.TimeUnit%29),因爲他們阻止。這將阻止循環在隊列中沒有任何內容時運行。那麼你應該也可以刪除手動的'sleep'。 – jpmc26

+0

你在allSymbolsSet中添加符號,但是你永遠不會刪除它們。所以在你的同時(真)你總是會打印你所有的符號 – fluminis

回答

1

我明白了。發生了什麼事:

您的循環開始,並且符號被添加到隊列中。它從線程循環中的隊列中取出,然後運行迭代器循環。然後外層循環(while (true))再次出現,這次沒有添加符號,但迭代器循環仍然執行。你需要的,如果一個新的符號已經被添加到只執行這個循環:

  boolean added = false; 
      while (priorityBlocking.peek() != null) { 
       added = true; 
       String symbol = priorityBlocking.poll(); 
       allSymbolsSet.add(symbol); 
       try { 
        System.out.println("Symbol From priorityBlocking" +" "+ symbol); 
       } catch (Exception e) { 
         e.printStackTrace(); 
       } 
      } 
      if (added) { 
       Iterator<String> ite = allSymbolsSet.iterator(); 
       while (ite.hasNext()) { 
        String symbol = ite.next(); 
        if (symbol != null && symbol.trim().length() > 0) { 
         try { 
          System.out.println("Symbol From allSymbolsSet"+" "+symbol); 
         } catch (Exception e) { 
          e.printStackTrace(); 
         } 
        } 
       } 
      } 

另外,使用takepoll(long,TimeUnit)也將停止你的循環,而你沒有什麼要補充的。這也應該避免循環的第二部分不必要地運行。你只需要處理InterruptedException

+0

我把你的代碼和運行,但我仍然看到迭代不斷執行。這是預期的,因爲一旦旗幟設置爲真,它會持續知道,請告訴我,如果我錯過了任何東西。 – Kiran

+0

該標誌位於'try'塊的本地。每次循環播放時它都會獲得新的值。如果你只添加一次,那麼它應該只執行一次。如果添加多個項目,每次添加內容時都會執行。 – jpmc26

+0

由於這是有道理的,試了一下,現在,似乎不錯,這是工作的罰款,但你能告訴我我得到了什麼好處,如果我使用採取從的PriorityBlockingQueue,而不是你粘貼上面的代碼。 – Kiran

相關問題