Java中避免超时/饥饿的常见做法?

Java中避免超时/饥饿的常见做法?,java,multithreading,synchronization,queue,Java,Multithreading,Synchronization,Queue,我有一个web服务,可以将文件写入磁盘,将其他内容写入数据库。每次写入整个操作需要1-2秒 该服务可以同时从多个客户端调用,但可能性不大。假设有20个客户端同时调用webservice,写入操作必须同步。在这种情况下,一些客户端可能会出现超时异常,因为它们必须等待数秒 有什么好的做法可以解决这种情况吗?现在,这些方法是同步的(这可能导致饥饿/超时) 我是否应该删除synchronized关键字,让所有线程进入write方法,并将其任务放入任务队列以避免超时?这是正确的解决方法吗?删除已同步的并将

我有一个web服务,可以将文件写入磁盘,将其他内容写入数据库。每次写入整个操作需要1-2秒

该服务可以同时从多个客户端调用,但可能性不大。假设有20个客户端同时调用webservice,写入操作必须同步。在这种情况下,一些客户端可能会出现超时异常,因为它们必须等待数秒

有什么好的做法可以解决这种情况吗?现在,这些方法是同步的(这可能导致饥饿/超时)


我是否应该删除
synchronized
关键字,让所有线程进入write方法,并将其任务放入任务队列以避免超时?这是正确的解决方法吗?

删除已同步的
并将其单独放入任务队列不会对您有帮助(因为这实际上是已同步的为您所做的事情)。但是,如果您在将web请求放入队列后立即响应它,那么您将减少响应时间。但要以一定的可靠性为代价,因为用户将得到确认,即工作已经完成,而工作不会真正完成(工作完成前系统可能会崩溃)。

弗朗西斯·厄普顿的做法确实是一种公认的做法

另一个是进行更细粒度的同步。您可以同步应该同步的不变量的访问,而不是同步类的所有读/写方法

但更好的是,完全摆脱同步。这是可能的使用包。这个包引入了使用(使用原子指令在java中实现)的新集合。这些集合(例如)在扩展时能够实现更好的吞吐量


您可以在中了解更多信息。

在这种类型的实现(负载增加时服务速度变慢)中,您希望尽可能实现异步,包括超时处理(如果基于服务器)和所需的I/O。不要让客户端响应线程等待这些耗时的操作,保留服务器对新请求的响应,而是启动所需的操作(可能是对动态线程池),并让回调处理结果,无论是超时、完成I/O还是错误

根据首先发生的情况发送适当的响应,但如果发送错误/超时消息,然后到达已完成的I/O(由于I/O和计时器之间的争用情况),请准备回滚I/O。这意味着服务器中需要事务语义


这是一个随着负载增长而变得越来越复杂的领域,但早期良好的设计应该允许您随着负载增长进行扩展。理想情况下,客户端服务线程不应该完全阻塞。

听起来客户端好像坏了。如果服务通常需要几秒钟,但客户端超时,则客户端超时过快。或者,如果客户应该很快超时,那么超时是正常的,客户必须优雅地与他们打交道。