[英]Java: How to start another thread of the same Object?
我正在尝试模拟某种“服务器”。 我有一个叫做Server的类,它扩展了Thread。 我有一个从1到1,000,000的循环,如果它取决于有多少服务器,则在内部循环,我想每次绕过该循环时都启动一个新线程,以便服务器拾取“请求”来执行它,将服务器标记为繁忙,然后停止此线程,将服务器标记为不繁忙,并等待新的“请求”。
当前,我得到了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;
}
}
}
这是您的方法存在的更多问题,但让我们从该方法开始。
在您的主机中,当您创建新服务器时,也要启动它们,而不要在“处理循环”中启动它们。
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
作为BlockingQueue<Request> requests
)。
您的服务器:
run() {
for(...) {
Request request = requests.take();
doSomething();
}
}
在你主要的地方
server.requests.add(request);
实际上,您应该定义一个请求的BlockingQueue,由所有服务器共享,这样,无论哪个服务器空闲,它都会从队列中抢占一个请求。 只需将请求队列作为构造函数参数,然后将其传递到服务器即可。
然后main会将请求分派到同一队列,并且任何可用服务器都将处理它们。
您无法重新启动已退出的Thread
,因为Thread.start()
的Javadoc以及抛出IllegalThreadStateException
状态的原因。
您将必须创建一个新线程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.