2011-03-28 57 views
0

我有一个从调用外部服务的servlet调用的代码。当然,不保证服务返回响应需要多长时间。我需要确保一次只能执行一次对此服务的调用,但当然servlet容器可以对servlet运行并发请求。我希望保证请求的优先级按照先到先服务器的原则处理单个文件。因此,我对外部servlet的调用是同步的是不够的,因为一旦当前调用完成,就不能保证哪个线程进入下一个调用。保证线程执行顺序是先到先服务

任何想法?

+0

您不必在请求多久才能到你的服务器的控制,所以无论如何,你真的不知道哪一个是第一个。我不会太担心这些请求的顺序,只是他们被隔离而不能互相交流。 – corsiKa 2011-03-28 17:46:38

+0

想象它需要20分钟来处理第一个请求。让1秒前发出的第n个请求在1到n-1之前执行,这可能是20分钟前来的吗?你可以用这种方式完全挨饿。 (是的20分钟是极端的,并会提出其他问题需要关注) – harschware 2011-03-28 18:14:07

+0

此外,你是对的,但它是一个问题的程度,我可以通过控制对这个潜在的长期运行资源的访问来缓解,而容器的请求不太可能长时间运行(我的应用程序是容器中唯一的一个)。 – harschware 2011-03-28 18:21:25

回答

4

你可以使用公平锁定

Lock lock = new ReentrantLock(true); 

这使得它在尝试的顺序锁。

+0

参见Java Concurrency in Practice的第13章,Bloch et al。 – harschware 2011-03-28 20:46:49

+0

这是一个很好的答案@彼得..但我认为公平的锁定工作后,等待阶段..意味着线程,有更多的时间在等待阶段首先激活。 – aditya 2012-12-25 12:24:21

+0

@Anita公平锁定有更多的开销,并且速度较慢。这就是为什么它不是默认行为。即你只有在真正需要的时候才会使用它。 – 2012-12-25 13:09:24

0

在你的servlet中创建一个工作线程,并在那里插入标注。请求处理将在向队列添加请求时进行同步,然后只需等待工作线程回报即可。

4

您可以使用single-threaded ExecutorServicesubmitCallable秒(这将执行实际要求),并等待Future价值become available

+0

我同意,但我想强调,这个预先配置的ExecutorService可以更好地满足OP的需求(并且文档清楚地表明任务是按顺序执行的):http://download.oracle.com/javase/1.5.0 /docs/api/java/util/concurrent/Executors.html#newSingleThreadExecutor() – akappa 2011-03-28 18:46:50

1

java.util.concurrent中的许多电力公司都适用于这种情况,Semaphore公平设置是另一种选择

import java.util.concurrent.*; 
Semaphore sem = new Semaphore (int n = HOW_MANY_PERMITS, boolean fairness = true);