Java线程睡眠

Java线程睡眠,java,multithreading,Java,Multithreading,我有一个主for循环,它向外部系统发送请求。外部系统可能需要几秒钟甚至几分钟才能做出响应。 此外,如果请求数达到MAX_请求数,则当前for循环应休眠几秒钟 这是我的设想。假设主for循环进入休眠状态(例如5秒),因为它已达到最大请求。然后假设以前的外部请求从callExternalSystem()返回。当前处于睡眠状态的for循环主线程会发生什么情况?它会被中断并继续处理还是继续睡眠 for(...){ ... while(numRequestsProcessing > MAX_

我有一个主for循环,它向外部系统发送请求。外部系统可能需要几秒钟甚至几分钟才能做出响应。
此外,如果请求数达到MAX_请求数,则当前for循环应休眠几秒钟

这是我的设想。假设主for循环进入休眠状态(例如5秒),因为它已达到最大请求。然后假设以前的外部请求从callExternalSystem()返回。当前处于睡眠状态的for循环主线程会发生什么情况?它会被中断并继续处理还是继续睡眠

for(...){
  ...
  while(numRequestsProcessing > MAX_REQUESTS){
     Thread.sleep(SLEEP_TIME);
  }
  ...
 callExternalSystem();

}

提前感谢。

除非您有一些代码来中断休眠线程,否则它将继续休眠,直到所需的时间过去。如果不希望发生这种情况,可以使用
wait()
/
notify()
而不是
sleep()
,这样另一个线程可以通知对象主线程正在睡眠,以便唤醒它。当然,这取决于是否有另一个线程注意到外部系统已经做出了响应——不清楚您是如何得到响应的


编辑:听起来你真的应该用一个。每当主线程想要发出请求时,它都会获得一个许可证。每次有响应,就会释放一个许可证。然后,您只需要使用您想要的并发请求的数量来设置它。如果您希望能够在主线程中指定超时,请使用
tryAcquire
,但如果您已经有了非常满意的大量未完成请求,请考虑您想要做什么。

除非您有一些代码来中断休眠线程,否则它将继续休眠,直到所需的时间过去。如果不希望发生这种情况,可以使用
wait()
/
notify()
而不是
sleep()
,这样另一个线程可以通知对象主线程正在睡眠,以便唤醒它。当然,这取决于是否有另一个线程注意到外部系统已经做出了响应——不清楚您是如何得到响应的


编辑:听起来你真的应该用一个。每当主线程想要发出请求时,它都会获得一个许可证。每次有响应,就会释放一个许可证。然后,您只需要使用您想要的并发请求的数量来设置它。如果您希望能够在主线程中指定超时,请使用
tryAcquire
,但如果您已经有了非常满意的大量未完成请求,请考虑您想要做什么。

我将使用java.util.concurrent.Executors创建一个线程池,其中包含MAX_请求线程。创建一个java.util.concurrent.CountDownLatch,用于一次发送多少请求。将闩锁传递给发出请求的可运行程序,它们在完成时调用闩锁上的倒计时()。然后,主线程调用闩锁上的wait(超时)。我还建议读一本书“Java并发性在实践中”。

我将使用Java.util.concurrent.Executors创建一个包含MAX_请求线程的线程池。创建一个java.util.concurrent.CountDownLatch,用于一次发送多少请求。将闩锁传递给发出请求的可运行程序,它们在完成时调用闩锁上的倒计时()。然后,主线程调用闩锁上的wait(超时)。我还建议您阅读《Java并发实践》一书。一种方法是使用ThreadPoolExecutor,它在没有空闲线程时阻塞

ThreadPoolExecutor executor = new ThreadPoolExecutor(MAX_REQUESTS, MAX_REQUESTS, 60, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new RejectedExecutionHandler() {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        try {
            executor.getQueue().offer(r, Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
});
for(int i=0;i<LOTS_OF_REQUESTS;i++) {
    final int finalI = i;
    executor.submit(new Runnable() {
        @Override
        public void run() {
            request(finalI);
        }
    });
}
ThreadPoolExecutor executor=new ThreadPoolExecutor(最大请求数,最大请求数,60,TimeUnit.SECONDS,new SynchronousQueue(),new RejectedExecutionHandler()){
@凌驾
public void rejectedExecution(可运行的r、线程池执行器执行器){
试一试{
executor.getQueue().offer(r,Long.MAX_值,时间单位纳秒);
}捕捉(中断异常e){
Thread.currentThread().interrupt();
}
}
});

对于(inti=0;i来说,一种方法是使用ThreadPoolExecutor,它在没有空闲线程时阻塞

ThreadPoolExecutor executor = new ThreadPoolExecutor(MAX_REQUESTS, MAX_REQUESTS, 60, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new RejectedExecutionHandler() {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        try {
            executor.getQueue().offer(r, Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
});
for(int i=0;i<LOTS_OF_REQUESTS;i++) {
    final int finalI = i;
    executor.submit(new Runnable() {
        @Override
        public void run() {
            request(finalI);
        }
    });
}
ThreadPoolExecutor executor=new ThreadPoolExecutor(最大请求数,最大请求数,60,TimeUnit.SECONDS,new SynchronousQueue(),new RejectedExecutionHandler()){
@凌驾
public void rejectedExecution(可运行的r、线程池执行器执行器){
试一试{
executor.getQueue().offer(r,Long.MAX_值,时间单位纳秒);
}捕捉(中断异常e){
Thread.currentThread().interrupt();
}
}
});

对于(int i=0;i+1,尽管我会更进一步,并说在这里使用睡眠进行调度是一种反模式。当然,有一些事件可以连接到入站响应,以使重新唤醒具有确定性?好的,谢谢。CallernalSystem()实际上创建了另一个线程来调用外部系统。当它得到响应时,它会将numRequestsProcessing减少1。这就是主for循环线程知道何时不再进入睡眠状态的方式。@Marquinio:对。该线程可以通知调用方……但还有一个更好的选择。编辑。我对线程不太熟悉s、 但是,在while循环中使用Thread.sleep()可能不是一个好主意我认为这样会更好,并且可能会提高for循环的性能。我下次会记住这一点。谢谢。+1尽管我会更进一步,并且说在这里使用sleep进行调度是一种反模式。当然,有一些事件可以挂接入站响应,以使重新唤醒具有确定性?好的,谢谢。callExternalSystem()实际上创建了另一个线程来调用外部系统。当它得到响应时,它将numRequestsProcessing减少1。这就是主for循环线程知道何时不再进入睡眠状态的方式。@Markinio:对。该线程可以