我有一些数据处理正在一个名为“myServlet”的 servlet 中执行(例如),有时我会同时收到大量要处理的数据,我的意思是同时 exaclty,我需要一种方法来告诉客户端服务器正忙。
我尝试在应用程序启动时将 ServletContext 中的一个属性初始化为 false,然后每当我收到请求时,我检查该属性是否为 false,如果是这样,我将其更改为 true,然后我以这种方式处理只要我正在处理,下一个请求就会被丢弃。当我同时收到多个请求时,这再次无法正常工作,服务器同时处理它们,我认为一些请求甚至在我将 ctx 属性更改为 TRUE 之前就逃脱了......我认为我'我遗漏了一些东西
这就是我想知道是否有办法检查是否已经有数据处理,以便我在那一点停止并将服务器忙响应发送给客户端
希望你们明白了(问题)
提前致谢...
最佳答案
您可以使用 ReentrantLock
(而不是上下文中的 boolean 值,在上下文中或某处持有此锁 - 它应该是跨所有对此 servlet 的请求的相同实例),您还需要同步锁定操作以确保您在服务器已经繁忙时将忙碌返回给任何将请求的人,阅读此类的 api 和示例,基本思想是:
public class SomeService {
private final ReentrantLock lock = new ReentrantLock(); // or store it in context based on your needs
// ...
/** this method refuse to process if there is already ongoing processing */
public void heavyProcessing() {
synchronized (lock) {
if (lock.isLocked()) {
// return busy status here
return;
}
lock.lock(); // acquire the lock - here we have the winner request that will be processed
}
try {
// ... do the processing here
} finally {
lock.unlock()
}
}
}
都是因为“乱序执行”。 ReentrantLock 是线程安全的,但 Boolean
或 boolean
不是。您还需要同步(同步
block )以确保您将正确的状态告知正在进行的处理过程中出现的请求。
因为:
如果线程之间没有适当的同步,就不能保证程序按照它编写的确切顺序执行(优化机制可以改变执行顺序,如果它不会影响单线程程序)。为防止此类 OOE 优化,您需要指定一些同步点。 ReenterantLock
的设计考虑到了这一点,boolean
不是。 ReenterantLock
的使用只是将此类同步点放入已执行的代码中,因此您可以获得正确的同步。
Java 中线程之间的同步是一个非常广泛的话题,我不能在这里教你如何去做。关于这个主题的一本好书是“Java Concurrency in Practice”。我建议先阅读这本书,然后在这里询问您是否会感到困惑。
关于java - 一种检查 servlet 是否已经在处理的方法 - j2ee?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40537135/