我希望服务器一次为一个客户端执行服务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。是否可能服务器端对客户端不公平,而不是首先运行最长等待客户端的请求?
编辑:实际上;公平甚至不是真正的问题。有时客户看起来只是挂在那个同步的部分;等待服务完成。
答案 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 它有助于理解线程的安排方式。