Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-如何在排队等待其他请求时一次发送一定数量的http请求_Java_Httprequest_Discord - Fatal编程技术网

Java-如何在排队等待其他请求时一次发送一定数量的http请求

Java-如何在排队等待其他请求时一次发送一定数量的http请求,java,httprequest,discord,Java,Httprequest,Discord,我正在开发一个discord机器人,它允许您使用JihanRESTAPI为myanimelist搜索动画。但是,API每秒只允许2个请求,任何违反该要求的行为都将导致IP禁令。因此,我必须将搜索函数(它将请求发送到JihanAPI)编程为一次只搜索两件事。然而,这比看起来要复杂得多 对于那些不知道Discord API是如何工作的人,有一个重写的message received方法,每当位于包含bot的服务器上的用户发送消息时,就会运行该方法。这个方法也有点像线程,因为每个发送消息的用户都会运行

我正在开发一个discord机器人,它允许您使用JihanRESTAPI为myanimelist搜索动画。但是,API每秒只允许2个请求,任何违反该要求的行为都将导致IP禁令。因此,我必须将搜索函数(它将请求发送到JihanAPI)编程为一次只搜索两件事。然而,这比看起来要复杂得多

对于那些不知道Discord API是如何工作的人,有一个重写的message received方法,每当位于包含bot的服务器上的用户发送消息时,就会运行该方法。这个方法也有点像线程,因为每个发送消息的用户都会运行一个单独的实例

这会使程序复杂化,因为如果有3个以上的用户同时搜索一部动画,我需要在排队等待第三部动画的同时发送两个请求,直到另外两个中的一个返回响应。但是,我还必须将该响应返回给发送它的
messageReceived
方法的实例


我真的没有任何代码可以显示。对于如何解决这个问题,我只希望能有一个解释、伪代码或java代码。多谢各位

我不确定我是否完全正确地解决了您的问题,但似乎您可以使用消费者/生产者模式解决这个问题,并在两者之间设置阻塞队列

因此,当用户发送消息时,它不会直接发送到JihanRESTAPI,而是作为任务提交到阻塞队列。这将是应用程序的一部分

消费者部分将通过获取队列的任务(用户消息)并发送请求来提交给JihanRESTAPI

通过将可调用项提交到包含两个线程的有界线程池,您可以确保每秒只提交和返回两个请求。由于Callable将一直阻塞到它完成为止,所以您可以在这两个过程之间留出一秒钟的时间。
或者你可以使用一个像信号灯这样的同步器,这将是一个更好的实践。

我看到了ilot的反应,我同意他的建议。他已经提到使用信号量将是一个好主意,我想我将分享一个使用该库的Java示例。我没有任何不和谐的经验,但希望你或其他人会发现这个例子很有用

import java.util.concurrent.Semaphore;

public class SemaphoreDemo {
    final static int TOTAL_REQUESTS = 10;
    final static int MAX_SIMULTANEOUS_REQUESTS = 2;
    final Semaphore semaphore;
    // the purpose of this array is for synchronization of the demo only
    final Thread[] threads = new Thread[TOTAL_REQUESTS];

    public static void main(String[] args) throws InterruptedException {
        new SemaphoreDemo().start();
    }

    SemaphoreDemo() {
        semaphore = new Semaphore(MAX_SIMULTANEOUS_REQUESTS);
    }

    void start() throws InterruptedException {
        System.out.printf("Start sending...             [permits = %d]\n", semaphore.availablePermits());

        // trigger incoming messages
        for (int i = 0; i < TOTAL_REQUESTS; i++) {
            messageReceived(new Request(i));
        }

        // synchronize with threads
        for (int i = 0; i < TOTAL_REQUESTS; i++) {
            threads[i].join();
        }

        System.out.println("Done!");
    }

    void messageReceived(Request request) {
        RequestHandler requestHandler = new RequestHandler(request, semaphore);
        Thread thread = createThread(request.i, requestHandler);
        thread.start();
    }

    Thread createThread(int i, RequestHandler requestHandler) {
        threads[i] = new Thread(requestHandler);
        return threads[i];
    }
}

class Request {
    final int i;

    Request(int i) {
        this.i = i;
    }

    void sendHttpRequest() {
        // do your thing
    }

    @Override
    public String toString() {
        return "Request " + i;
    }
}

class RequestHandler implements Runnable {
    final Request request;
    final Semaphore semaphore;

    RequestHandler(Request request, Semaphore semaphore) {
        this.request = request;
        this.semaphore = semaphore;
    }

    @Override
    public void run() {
        try {
            // try to acquire one of the permits if available, else wait...
            semaphore.acquire();

            System.out.printf("%s: sending request   [permits = %d]\n", request, semaphore.availablePermits());

            // Simulate sending a request with a random response time between 0 and 3 seconds
            request.sendHttpRequest();
            Thread.sleep(Math.round(3000 * Math.random()));

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // the request succeeded or was interrupted; always release the permit so another request can take it 
            semaphore.release();
            System.out.printf("%s: received response [permits = %d]\n", request, semaphore.availablePermits());
        }
    }
}
请注意,请求可能会按顺序结束,但总有0到2个可用许可证

Start sending...             [permits = 2]
Request 0: sending request   [permits = 1]
Request 1: sending request   [permits = 0]
Request 1: received response [permits = 1]
Request 2: sending request   [permits = 0]
Request 2: received response [permits = 1]
Request 3: sending request   [permits = 0]
Request 0: received response [permits = 1]
Request 4: sending request   [permits = 0]
Request 3: received response [permits = 1]
Request 5: sending request   [permits = 0]
Request 4: received response [permits = 1]
Request 6: sending request   [permits = 0]
Request 5: received response [permits = 1]
Request 7: sending request   [permits = 0]
Request 6: received response [permits = 1]
Request 8: sending request   [permits = 0]
Request 8: received response [permits = 1]
Request 9: sending request   [permits = 0]
Request 9: received response [permits = 1]
Request 7: received response [permits = 2]
Done!