1

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

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。服务器端是否可能对客户端不公平并且没有首先运行等待时间最长的客户端请求?

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

4

2 回答 2

3

首先你的锁对象总是应该被声明final。这并不能解决任何问题,但它会告诉您是否编写了错误的代码(例如在某处将锁设置为不同的锁)。

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

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

finally 只是一种安全措施,如果里面的任何部分抛出异常。

除此之外,您的代码看起来非常好,因此问题很可能在数据库中,而不是由使用同步引起的。

于 2013-11-11T13:37:21.363 回答
0

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

阅读文章:http ://www.javaworld.com/javaworld/jw-07-2002/jw-0703-java101.html 这对理解线程的调度方式很有帮助。

于 2013-11-11T10:53:05.757 回答