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

标签 java multithreading

我正在尝试模拟某种“服务器”。我有一个名为 Server 的类,它扩展了 Thread。我有一个从 1 到 1,000,000 的循环,如果它取决于有多少服务器,我想在每次循环时启动一个新线程,以便服务器拾取“请求”执行它并将服务器标记为繁忙,然后停止该线程 将服务器标记为不繁忙并等待新的“请求”。

目前我得到java.lang.IllegalThreadStateException,从我读到的内容是因为我试图启动同一个线程。我怎样才能解决这个问题并实现我想要的?

服务器.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 作为实现。)

您的服务器:

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

在你的主目录中的某个地方

server.requests.add(request);

实际上,您应该定义一个请求的阻塞队列,该队列由所有服务器共享,这样无论哪一个服务器空闲,它都会从队列中抢夺请求。只需将请求队列作为构造函数参数并将其传递到您的服务器即可。

然后 main 会将请求分派(dispatch)到同一个队列,并且它们将由任何可用的服务器处理。

关于Java:如何启动同一个对象的另一个线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29595847/

相关文章:

java - 使用java更新文本文件

java - 如何在android中使用TextWatcher进行查询?

java - 如何同步 2 个作业/进程

ios - UITableView reloadData异步

java - Guice Assisted Inject 具有多种接口(interface)实现

java - ThreadPoolExecutor:当一个任务返回错误时从 invokeAll() 取消任务

java - 如何向顶点添加鼠标监听器 - jgraphx

swift - 从另一个线程获得结果后如何更新 Realm 对象?

Python 子进程管道 block

multithreading - 我不懂多线程编程