简体   繁体   English

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

[英]Java: How to start another thread of the same Object?

I am trying to simulate some kind of "Servers". 我正在尝试模拟某种“服务器”。 I have a class called Server which extends Thread. 我有一个叫做Server的类,它扩展了Thread。 I have a loop going from 1 to 1,000,000 and inside if it depending on how many servers there are, I want to start a new thread each time it goes around the loop, in order the server to pick up a "request" executes it and mark the server as busy and then stop this thread mark server as not busy and wait for new "requests". 我有一个从1到1,000,000的循环,如果它取决于有多少服务器,则在内部循环,我想每次绕过该循环时都启动一个新线程,以便服务器拾取“请求”来执行它,将服务器标记为繁忙,然后停止此线程,将服务器标记为不繁忙,并等待新的“请求”。

Currently I get java.lang.IllegalThreadStateException and from what I read is because I am trying to start the same thread. 当前,我得到了java.lang.IllegalThreadStateException ,从我读到的内容是因为我试图启动同一线程。 How can I go around this and implement what I want ? 我该如何解决并实现我想要的?

Server.java 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 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;
            }
        }
    }   

That are more problems with your approach but let's start with that one. 这是您的方法存在的更多问题,但让我们从该方法开始。

In your main, when you create new servers, start them as well, and do not start them in the "processing loop". 在您的主机中,当您创建新服务器时,也要启动它们,而不要在“处理循环”中启动它们。

for(int i = 0; i < numberOfServers; i++)
{
    servers.add(new Server(i, executionTime));
}
for (Server s : servers) s.start();

OK, now your servers, would start and probably finish their run before main would manage to give them some work. 好的,现在您的服务器将启动,并且可能会在main设法给它们提供一些工作之前完成其运行。

So, in the begginig of run they should wait for something to work with. 因此,在开始运行时,他们应该等待可以使用的东西。 There are object.wait() and object().notify() you could use for that, but you should probably go directly to the "correct" solution. 您可以使用object.wait()和object()。notify(),但您应该直接使用“正确的”解决方案。

Servers, are meant to wait for the request which probably form a some queue (if they come faster then server can handle them). 服务器是为了等待可能形成队列的请求(如果它们来得更快,则服务器可以处理它们)。 You already have List<Request> requests that you probably wanted to use like this in your code. 您已经有想要在代码中像这样使用的List<Request> requests But simple list does not provide you with this "wait" option. 但是简单的列表无法为您提供此“等待”选项。

Use BlockingQueue<Request> requests instead (and for example LinkedBlockingQueue as impl.) 请改用BlockingQueue<Request> requests (例如,将LinkedBlockingQueue作为BlockingQueue<Request> requests )。

Your server: 您的服务器:

run() {
    for(...) {
        Request request = requests.take();
        doSomething();
    }
}

And somewhere in your main 在你主要的地方

server.requests.add(request);

In reality, you should rather define one BlockingQueue of the requests, which is shared by all the servers, that way whichever server is free it will snatch a request from the queue. 实际上,您应该定义一个请求的BlockingQueue,由所有服务器共享,这样,无论哪个服务器空闲,它都会从队列中抢占一个请求。 Simply make the requests queue as the constructor parameter and pass it to your servers. 只需将请求队列作为构造函数参数,然后将其传递到服务器即可。

Then main will dispatch the requests to the same queue and they will be processed by any available server. 然后main会将请求分派到同一队列,并且任何可用服务器都将处理它们。

You can't restart a Thread that has exited, as the Javadoc for Thread.start() and the reason given for throwing IllegalThreadStateException states. 您无法重新启动已退出的Thread ,因为Thread.start()的Javadoc以及抛出IllegalThreadStateException状态的原因。

You will have to create a new thread. 您将必须创建一个新线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM