我正在尝试模拟某种“服务器”。我有一个名为 Server 的类,它扩展了 Thread。我有一个从 1 到 1,000,000 的循环,如果它取决于有多少服务器,我想在每次循环时启动一个新线程,以便服务器拾取“请求”执行它并将服务器标记为繁忙,然后停止该线程 将服务器标记为不繁忙并等待新的“请求”。
目前我得到java.lang.IllegalThreadStateException
,从我读到的内容是因为我试图启动同一个线程。我怎样才能解决这个问题并实现我想要的?
服务器.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;
}
}
}
最佳答案
您的方法存在更多问题,但让我们从这个开始。
在主程序中,当您创建新服务器时,也启动它们,并且不要在“处理循环”中启动它们。
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
作为实现。)
您的服务器:
run() {
for(...) {
Request request = requests.take();
doSomething();
}
}
在你的主目录中的某个地方
server.requests.add(request);
实际上,您应该定义一个请求的阻塞队列,该队列由所有服务器共享,这样无论哪一个服务器空闲,它都会从队列中抢夺请求。只需将请求队列作为构造函数参数并将其传递到您的服务器即可。
然后 main 会将请求分派(dispatch)到同一个队列,并且它们将由任何可用的服务器处理。
关于Java:如何启动同一个对象的另一个线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29595847/