簡體   English   中英

Java:如何啟動同一對象的另一個線程?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM