我正在尝试模拟某种"服务器"。我有一个名为Server的类,它扩展了Thread。我有一个从1到1,000,000的循环内部,如果它取决于有多少服务器,我想每次循环时启动一个新线程,以便服务器选择"请求&# 34;执行它并将服务器标记为忙,然后将此线程标记服务器停止为忙碌并等待新的"请求"。
目前我得到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;
}
}
}
答案 0 :(得分:1)
这是你的方法的更多问题,但让我们从那个开始。
在您的主要内容中,当您创建新服务器时,也要启动它们,并且不要在“处理循环”中启动它们。
for(int i = 0; i < numberOfServers; i++)
{
servers.add(new Server(i, executionTime));
}
for (Server s : servers) s.start();
好的,现在你的服务器将启动并可能在main将设法给他们一些工作之前完成他们的运行。
所以,在运行的开头,他们应该等待一些事情可以解决。您可以使用object.wait()和object()。notify(),但您可能应该直接使用“正确”的解决方案。
服务器,意味着等待可能形成某个队列的请求(如果它们来得更快,那么服务器可以处理它们)。您已经在代码中使用了List<Request> requests
这样的代码。但是简单列表并没有为您提供这种“等待”选项。
改为使用BlockingQueue<Request> requests
(例如LinkedBlockingQueue
作为impl。)
您的服务器:
run() {
for(...) {
Request request = requests.take();
doSomething();
}
}
在你主要的某个地方
server.requests.add(request);
实际上,您应该定义一个由所有服务器共享的请求的BlockingQueue,这样无论哪个服务器都是空闲的,它都会从队列中抓取请求。只需将请求队列作为构造函数参数并将其传递给您的服务器。
然后,main会将请求分派到同一个队列,任何可用的服务器都会处理它们。
答案 1 :(得分:0)
您无法重新启动已退出的Thread
作为Thread.start()
的Javadoc以及投掷IllegalThreadStateException
州的原因。
您必须创建一个新主题。