2017-07-02 58 views
1

我想使用Servlets(resteasy + Hibernate)实现预约队列。我的预约管理员 如下(当然简化)。Java静态同步vs BlockingQueue实现

public class AppoController{ 

public synchronized static int createAppoinment(AppObj app){ 
    //get last app no 
    //insert new app with no+1 
    //return new app no 
} 
} 

目前这种方法工作正常。但我已阅读有关BlockingQueue实现这似乎是正确的方式?做工精细的

定义:
如果我不使用同步的静态和一次多个约会发送多个请求具有相同的任命没有
但是,如果使用同步静态,约会与正确的顺序创建

我没有在这里使用任何线程,但我认为tomcat使用自己的线程来从用户的服务器http请求。 所以这是一个多线程的应用程序?

我用Google搜索它过去几天,但我得到的最接近的是Java/Android: Synchronized vs Queue implementation

什么,我需要澄清的是,
- 这是做到这一点的正确方法吗?
- 对我的场景使用同步静态vs BlockingQueue实现有什么优点和缺点。

任何你看起来相关的其他输入也是受欢迎的。谢谢。

+0

我认为这并不重要,因为这两种方法都局限于单个JVM。如果您的服务受欢迎,那么单个tomcat实例将无法处理所有流量。但是如果你将服务部署到第二个独立的tomcat实例,两种方法都不能保证唯一的预约号码。因此解决这个问题的正确方法是让数据库生成预约号码。 –

+0

+1提升缩放的影响。已经完全错过了那部分!只是一个简单的问题,是否有可能在同步静态方法中耗尽服务器线程,因为它们被阻塞(等待)?和阻塞队列相反,线程(生产者)永远不会被阻塞? – eric

+0

是的,但它是(a)已弃用,(b)计划搬迁,和(c)绝对是你想要的最后一件事。只需同步您需要同步的内容,或者使用'java.util.concurrent.'中的某些内容' – EJP

回答

0

您的实施确实有效。同步方法只能由一个线程随时执行。 Tomcat将使用多个线程(细节取决于当前设置,假设每个请求有一个线程),因此每个并发请求都会获得自己的线程,然后请求等待此方法,直到其线程被允许进入方法。

我看到两个选项,根据您的需要。

  1. 如果约会来自数据库,让数据库或hibernate处理id生成。这会将多线程问题转移到专为处理这类问题而设计的数据库中。
  2. 如果约会不是来自数据库,并且您只需要约会对象的唯一标识符,请使用UUID(例如, java.lang.UUID.randomUUID()

实际上,如果您想要将约会的创建从HTTP请求中移出,实际上只使用Queue是有意义的。例如。如果在请求完成后像每夜批处理作业或专用工作线程池那样创建预约。但是,如果创建约会是一项昂贵的操作,这只会有意义。

在另一个主题上,你应该检查这个方法是否需要是静态的。

+0

是的约会可以使用oninsert触发器从数据库生成(我有几个条件来确定新的应用程序否)。应用程序没有创建是直接过程与百名用户试图访问有限的应用程序没有插槽集。 – eric

+0

'不会扩展'是夸大的多报。 *任何*解决方案都会涉及某种同步,信号量或锁定。它的扩展程度完全取决于同步/信号量/锁的* duration *。你自己的解决方案在这方面没有什么不同。 – EJP

+0

是啊,“不会规模”是过度夸张。我想指出的是,自己解决多线程问题通常是一个糟糕的主意。只需将问题移至专为此类问题设计的系统,如数据库即可。 –