2013-05-09 12 views
0

我一直在尋找類似的問題,但對於我的要求,我想我需要一些特殊的東西,我會詳細解釋它。如何爲Java併發應用程序制定優化方案?

首先我需要遷移其使用這種方式工作的系統:

  1. 稱爲ServerPool(線程)類與主類初始化。
  2. 這ServerPool創建隊列來接收插座和一個矢量來管理工作者線程(S.

所以在游泳池的代碼,我有以下幾點:

public class ServerPool extends Thread { 
    private LinkedBlockingQueue<SearchQuery> workQueue; //SearchQuery is a Class I defined which can handle two type of processes (for sockets and for single Strings) 
    private Vector<SearchThread> workers; 
    private final int NTHREADS = 10; 
    private int typeOfQuery; 

    public ServerPool() { 
    workers = new Vector<SearchThread>(NUM_THREAD); 
    workQueue = new LinkedBlockingQueue<SearchQuery>(); 
    this.typeOfQuery = typeOfQuery; 
    SearchThread search = new SearchThread(workQueue); 
    search.start(); 
    workers.add(search); 
} 

public void run() { 
    while(true){ 
    SearchQuery client = null; 

    if (typeOfQuery == 1) { 
     client = new SocketQuery(....); 
     } else if (typeOfQuery == 2) { 
     client = new StringQuery(...); 
     } 
     workQueue.put(client); 
} 
} 

對於執行該SearchThread過程:

public class SearchThread extends Thread { 
    private LinkedBlockingQueue<SearchQuery> workQueue = null; 
    private SearchQuery request = null; 

    public SearchThread(LinkedBlockingQueue<SearchQuery> workSource) { 
     workQueue = workSource; 
    } 

    public void run() { 
     request = workQueue.take(); 
     //Here I process the request 
     //And use a PrintWriter to give a "response"    
    } 

} 

這曾經使用帶有插座telnet來工作,但現在我已經被要求將其轉換成Web服務,從而爲Web服務是應該返回一個值,所以我想利用可贖回,未來和線程池的,但我不能複製完全一樣的行爲,我試圖實現這一點:

public class NewServerPool { 

    private final int NTHREADS = 10; 
    private ExecutorService executor; 
    private LinkedBlockingQueue<SearchQuery> workQueue; 
    private Vector<Future<String>> futures; 
    private boolean end = true; 

    public NewServerPool(int port, SearchQuery typeOfQuery) { 
     executor = Executors.newFixedThreadPool(NTHREADS); 
     workQueue = new LinkedBlockingQueue<SearchQuery>(); 
     futures = new Vector<Future<String>>(); 

    } 


} 

而對於搜索線程,現在它是一個Callable

public class NewSearchThread implements Callable<String>{ 

    private SearchQuery searchQuery; 

    public NewSearchThread(SearchQuery searchQuery) { 
     this.searchQuery = searchQuery; 
    } 

    @Override 
    public String call() throws Exception { 
     String xmlResponse = null; 

     if (searchQuery == null) { 
      throw new InvalidSearchQueryException("The search query is not valid or has null value: " + searchQuery); 
     } 

     if (searchQuery instanceof SocketTimed) { 
      System.out.println("It is socket timed query type"); 
     } else if (searchQuery instanceof WebServiceQuery) { 
      System.out.println("It is a web service query type"); 
     } 

     xmlResponse = searchQuery.manageResponse(); 

     return xmlResponse; 
    } 

所以我得在服務器池中stucked,asumming我的WebService將調用服務器池(NewServerPool)在這種情況下的一個新實例,我怎麼能繼續嗎?如果有人能幫助我,我會很感激。 在此先感謝,最好的問候。

+0

與舊版本是工作線程操縱套接字還是被方法調用包裝? – BevynQ 2013-05-09 21:52:57

+0

工作線程操縱套接字。他遲遲沒有迴應。 – 2013-05-10 12:20:06

回答

2

幾件事情:

首先,你原來ServerPool類是有缺陷的,因爲它永遠只能實例的SearchThread 1個實例。我想你的意思是開始NTHREADS(10)SearchThread s。

下,它看起來像你從SearchThread改變NewSearchThread的方法略有 - 在爲NewSearchThread構造需要一個SearchQuery的說法,而SearchThread需要SearchQuery關閉BlockingQueue的。

最後你NewServerPool類的不同之處,從ServerPool其做法,在ServerPoolrun()方法不斷則以新SearchQuery S插入BlockingQueue。相比之下,NewServerPool的構造函數只需要一個單獨的SearchQuery,並且不執行任何操作。

如何這樣的事情,讓你開始:

public class NewServerPool extends Thread { 

    private final int NTHREADS = 10; 
    private ExecutorService executor; 
    private Vector<Future<String>> futures; 

    public NewServerPool(int port, SearchQuery typeOfQuery) { 
     executor = Executors.newFixedThreadPool(NTHREADS); 
     futures = new Vector<Future<String>>(); 
    } 

    public void run() { 
     while(true){ 
      SearchQuery client = null; 

      if (typeOfQuery == 1) { 
       client = new SocketQuery(....); 
      } else if (typeOfQuery == 2) { 
       client = new StringQuery(...); 
      } 
      futures.add(executor.submit(new NewSearchThread(client))); 
     } 
    } 
} 

請注意,我說:「讓你開始」 ......如上面還需要一些補充,如run()方法時的適當退出現在是時候停止調遣請求了(但那是另一個話題)。

+0

謝謝,對於延遲響應抱歉,但我仍然對這種情況不熟悉,我知道需要添加一些附加內容,但是如何從run方法返回值?我的服務的Web方法應該啓動ServerPool,然後返回一個值,但我不確定如何實現這一點。 – 2013-05-13 12:21:47

2

如果你只是想「啓動」線程池並返回一個值,那麼聽起來不像是有什麼理由讓你的NewServerThreadPool擴展Thread(但不知道你想要實現什麼的完整規範我不是100%確定的)。你的啓動方法應該返回什麼類型的值? booleanStringint?你可以改爲嘗試這樣的事情:

public class NewServerPool { 

    private final int NTHREADS = 10; 
    private ExecutorService executor; 
    private Vector<Future<String>> futures; 

    public NewServerPool(int port, SearchQuery typeOfQuery) { 
     futures = new Vector<Future<String>>(); 
    } 

    public boolean launchThreadPool() { 
     executor = Executors.newFixedThreadPool(NTHREADS); 
     return true; 
    } 

    public void submitToThreadPoolForProcessing(SearchQuery client) { 
     futures.add(executor.submit(new NewSearchThread(client))); 
    } 

    public Vector<Future<String>> getFutures() { 
     return futures; 
    } 
} 

注意的是,在上述情況,launchThreadPool()方法的單線路的內容可以很容易地被構造的一部分(因爲它是在以前的帖子),但是將它分解成它自己的方法允許你在啓動線程池之後返回值,如圖所示它將返回一個boolean的值(總是返回true),但是你當然可以改變方法來返回你的規範調用的任何類型