Java:如何启动同一个Object的另一个线程?

时间:2015-04-12 23:24:58

标签: java multithreading

我正在尝试模拟某种"服务器"。我有一个名为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;
            }
        }
    }   

2 个答案:

答案 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州的原因。

您必须创建一个新主题。