GWT - 服务器端同步块

时间:2013-11-11 09:48:05

标签: java multithreading gwt synchronized

我希望服务器一次为一个客户端执行服务impl代码的某个部分,线程安全;并顺序。以下是执行此操作的服务器端服务实现的一部分:

public BorcData getBorcData(String userId) throws GeneralException, EyeksGwtException
{
        StoredProcedure sp = DALDB.storedProcedure("BORCBILDIRIM_GETMUKDATA_SP");
        DALResult spResult;
        Row spRow;
        String vergiNo;
        String asamaOid;

        synchronized (ServerUtility.lock_GeriArama_GetBorcData_GetMukDataSP)
        {
            String curOptime =CSDateUtility.getCurrentDateTimeToSave();

            sp.addParam(curOptime);
            spResult = sp.execute();

            if (!spResult.hasNext())
            {
                throw new GeneralException("53", "");
            }
        }

您会看到已同步的块。我用于锁定的对象定义为:

public static Object lock_GeriArama_GetBorcData_GetMukDataSP = new Object();

我的问题是:我想我看到当客户端等待长时间执行同步块时,其他一些客户端调用了这个服务并执行了该块而没有排队并继续。第一个客户还在等。

我知道服务器端运行的是纯Java。是否可能服务器端对客户端不公平,而不是首先运行最长等待客户端的请求?

编辑:实际上;公平甚至不是真正的问题。有时客户看起来只是挂在那个同步的部分;等待服务完成。

2 个答案:

答案 0 :(得分:3)

首先,您的锁定对象始终应声明为final。这不是解决任何问题,但是它会告诉您是否编写了错误的代码(例如将锁设置为某个地方的其他锁)。

确保公平性的一种方法是使用ReentrantLock初始化为true(公平调度)。它将确保客户端不会无限期挂起,但会以FIFO顺序执行。好处是,只需对代码进行微小更改,方法是将所有同步块替换为:

lock.lock();
try { 
  // previous code
} finally {
  lock.unlock();
}

最终只是一个安全措施,如果内部的任何部分抛出异常。

除此之外,您的代码看起来非常精细,因此问题最有可能出现在数据库中,而不是由于使用了同步。

答案 1 :(得分:0)

java中的多线程并不能保证顺序执行。

阅读文章:http://www.javaworld.com/javaworld/jw-07-2002/jw-0703-java101.html 它有助于理解线程的安排方式。