2011-06-25 21 views
0

我有一个与服务器通信的客户端应用程序。在这个应用程序中,客户可以向服务器发送请求以保留酒店房间。 问题是,如果我剩下一个房间,可能有两个客户预订。如何在Java中执行服务器端的线程安全方法?

我不知道如何避免它,因为这个原因,我没有代码实现显示。 如果我不得不猜测,我会像一个单身人士一样实施。

if (availableRooms()>0) { 

     synchronized(syncObject_) { 

     if (availableRooms()>0) { 
      makeReservation() 
     } 

     } 

    } 
    return instance_; 
    } 

这是一个可接受的解决方案吗?它工作吗?

+0

@little bunny foo foo问题是为什么他使用'双重检查锁定'。如果他在您提出建议或通过单独的对象同步“this”是另一个决定。两者都有优势:第一个更好的可读代码后者更强大。数据库事务在这里很好,但在每个DBMS中都不可用。 –

回答

3

只有当您只有一台服务器时,此功能才有效。如果您需要扩展,请求可能会发送到不同的服务器,并且同步不起作用。在这种情况下,你可能会使用数据库,你应该使用数据库事务。

+0

+1 for db交易 –

+0

这是正确的建议:使用数据库事务或存储过程来预留房间。数据库是唯一可以成功实现互斥的地方。 –

+0

@凯尔伯顿这是非常教条的观点。您可以在需要在应用程序级别进行同步的拓扑中,即在涉及多个数据库时,或者只是您没有数据库事务的其他数据源时进行同步。说同步只能在DB中完成是完全错误的。 尽管如此,在大多数情况下,这是最好的建议,我同意。 –

-1

您的代码看起来像double check idiom

但是你的想法很好,只要你只有一个单身你同步。 (在你的例子中,它是syncObject_。)当你有更多的服务器运行负载平衡时,你可能会有更多。有一个单身人士进行预订,并在一个同步范围内检查免费房间和预订本身。

-1

为了避免让两个人保留同一房间,您必须确保只有一个线程可以访问提供房间的任何对象。最可读的方式做,这将是在这种情况下,提供客房预订服务,以便在对象上同步,你很可能做

synchronized(this){ 
    //... 
    makeReservation() 
    //... 
} 

但是,只要有只有一个适用于所有的_syncObject实例线程和代码中没有其他地方可以调用makeReservation(),您的方法也可以。

请注意,如果您使用的是数据库,则可以简单地将数据库的隔离级别设置为SERIALIZABLE,为数据库事务执行makeReservation(),数据库将为您处理所有这些问题。

+0

即使通常在Java中完成,我也强烈建议不要在'this'上同步。这是我在C#世界学到的,我认为他们是对的,当他们说你无法控制其他人在你的对象上同步时。因此,请始终在您的私人虚拟对象上同步。 我不是微软的粉丝,但我认为他们就在这里:http://msdn.microsoft.com/en-us/library/c5kehkcz%28v=vs.80%29.aspx –