Question

I want the server to execute a certain part of the service impl code for one client at a time, thread-safe; and sequentially. Here's the part of the server-side service implementation that does this:

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", "");
            }
        }

You see the synchronized block. The object that I use for the lock is defined as:

public static Object lock_GeriArama_GetBorcData_GetMukDataSP = new Object();

My problem is: I think I saw that while a client was waiting to execute that synchronized block for a long time, some other client called this service and executed that block without getting in line and went on. The first client was still waiting.

I know that the server-side runs pure Java. Is it possible that the server-side is being unfair to the clients and not running the longest waiting client's request first?

EDIT: Actually; the fairness isn't even the real problem. Sometimes clients look like they just hang in that synchronized part; waiting forever for the service to finish.

Was it helpful?

Solution

First your lock Object always should be declared final. This isn't fixing any problems, but it tells you if you did code something wrong (like setting the lock to a different lock somewhere).

One way to ensure fairness is to use a ReentrantLock initialized with true (fair scheduling). It will ensure that clients do not hang indefinitely, but are executed in a FIFO order. The good thing is that this requires only a minor change to your code, by replacing all those synchronized blocks with:

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

The finally is just a safety measure, should any part inside throw an exception.

Other than that your code looks perfectly fine, so the issue is most likely in the DB and not caused by using synchronized at all.

OTHER TIPS

Multi threading in java doesn't guarantee sequential execution.

Read the article : http://www.javaworld.com/javaworld/jw-07-2002/jw-0703-java101.html It is much helpful in understanding how threads are scheduled.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top