简体   繁体   中英

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. 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".

Currently I get java.lang.IllegalThreadStateException and from what I read is because I am trying to start the same thread. How can I go around this and implement what I want ?

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;
            }
        }
    }   

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.

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.

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. But simple list does not provide you with this "wait" option.

Use BlockingQueue<Request> requests instead (and for example LinkedBlockingQueue as impl.)

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. 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.

You can't restart a Thread that has exited, as the Javadoc for Thread.start() and the reason given for throwing IllegalThreadStateException states.

You will have to create a new thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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