0

I have the following code for locking an object with a particular user ID

 public boolean acquireLock(Long id) {
   if (lock.compareAndSet(0L, id)) { 
    return true ; 
  }
  return false ; 
}

I acquire it in the following way:

      while(!parent.acquireLock(id)){
        System.out.println(lock.get());
        if (count++>1000000) {
          System.out.println(id + " Trying to acquire " + lock.get());
          DebugHandler.createException("Error, deadlock");

        }
      }

Release it as :

public boolean releaseLock(Long id) { 

  if (lock.compareAndSet(id, 0)) {
    System.out.println("Releasing Lock for " + id);
    return true ; 
  }
  else { 
    DebugHandler.createException("Lock not owned by current view. Thief");
    return false ;
  }

}

And declare the lock object as:

 private volatile AtomicLong lo = new AtomicLong(0); 

except that I get the following odd behaviour and deadlock, which concludes with:

Id 45 trying to acquire 0

Ak, the value of the lock is systematically 0 but the compare and swap test fails, believing it isn't 0. (the counter to test for deadlock is reinitialised after I exit the loop)

Any ideas?

4

1 回答 1

0

I can see a problem with your code. If you ever get some thread with an id that is zero, your locking scheme will break down, and two threads can end up holding the lock at the same time.

Fix: Add a defensive check to your acquireLock and releaseLock methods to test that the id is non-zero.

As to how your code might get into an apparently deadlocked state:

  • It could really be a real deadlock. For instance, this could happen if a thread tries to acquire the lock for a given id when it already holds the lock for that id. (Your lock as implemented is non-reentrant.)

  • Your code could have failed to release the lock for a given id; e.g. because an exception was thrown and the normal call to releaseLock was skipped.

于 2013-10-05T23:51:28.817 回答