2015-04-12 257 views
0

我想模擬某種「服務器」。我有一個名爲Server的類擴展了Thread。我有一個從1到1,000,000的循環,如果它取決於有多少服務器,我想在每次循環時啓動一個新線程,以便服務器接收「請求」執行它並且將服務器標記爲繁忙,然後停止此線程標記服務器爲不忙,並等待新的「請求」。Java:如何啓動同一對象的另一個線程?

目前我得到java.lang.IllegalThreadStateException從我讀的是因爲我試圖啓動相同的線程。我怎樣才能解決這個問題並實現我想要的?

Server.java

public class Server extends Thread 
{ 
    boolean isBusy = false; 
    int executionTime; 
    int serverId; 
    List<Request> requests = new ArrayList<Request>(); 
    Request currentRequest; 

    public Server(int requiredServerId,int requiredExecutionTime) 
    { 
     this.serverId = requiredServerId; 
     this.executionTime = requiredExecutionTime; 
    } 

    @Override 
    public void run() 
    { 
     isBusy = true; 
     for(int time = 1; time <= executionTime; time++) 
     { 
      if(time == executionTime) 
      { 
       isBusy = false; 
       currentRequest.setFinish(); 
       break; 
      } 
     } 
    } 

    public void fetch(Request request) 
    { 
     requests.add(request); 
     currentRequest = request; 
    } 
} 

Main.java

// Create Servers 
    List<Server> servers = new ArrayList<Server>(); 
    for(int i = 0; i < numberOfServers; i++) 
    { 
     servers.add(new Server(i, executionTime)); 
    } 

    // Create Queue 
    List<Integer> queue = new ArrayList<Integer>(); 

    for(int time = 1; time <= runningTime; time++) 
    { 
     if(time % arrivalTime == 0) 
     { 
      if(queue.size() <= queueSize) 
      { 
       queue.add(time); 
      } 
      else 
      { 
       rejectedRequests += 1; 
      } 
     } 

     if(!queue.isEmpty()) 
     { 
      for(Server server : servers) 
      { 
       if(server.isBusy == false) 
       { 
        Request request = new Request(queue.get(0)); 
        queue.remove(0); 
        server.fetch(request); 
        server.start(); 
       } 
       break; 
      } 
     } 
    } 

回答

1

這是更多的問題與您的方法,但讓我們開始的那一個。

在你的main中,當你創建新的服務器時,也要啓動它們,並且不要在「處理循環」中啓動它們。

for(int i = 0; i < numberOfServers; i++) 
{ 
    servers.add(new Server(i, executionTime)); 
} 
for (Server s : servers) s.start(); 

OK,現在你的服務器,就開始和可能結束其運行之前,主要將設法給他們一些工作。

因此,在開始運行時,他們應該等待一些東西來處理。您可以使用object.wait()和object()。notify(),但您應該直接轉到「正確」解決方案。

服務器,意味着等待可能形成一個隊列的請求(如果它們來得快,那麼服務器可以處理它們)。你已經有了List<Request> requests,你可能想在你的代碼中使用這樣的代碼。但簡單的列表不會爲您提供此「等待」選項。

使用BlockingQueue<Request> requests來代替(例如LinkedBlockingQueue爲IMPL。)

您的服務器:

run() { 
    for(...) { 
     Request request = requests.take(); 
     doSomething(); 
    } 
} 

而且地方你的主要

server.requests.add(request); 

在現實中,你倒是應該定義一個BlockingQueue由所有服務器共享的請求,無論哪種服務器都是免費的,它將從該qu奪取請求EUE。只需將請求隊列作爲構造函數參數傳遞給您的服務器即可。

然後main會將請求發送到同一隊列,並且它們將被任何可用的服務器處理。

0

您無法重新啓動已退出的Thread,因爲Javadoc對於Thread.start()以及給出的投擲原因IllegalThreadStateException的狀態。

您將不得不創建一個新線程。

相關問題