2015-04-12 67 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的状态。

您将不得不创建一个新线程。

相关问题