@ -20,8 +20,8 @@ import java.util.Arrays;
import java.util.Collection ;
import java.util.HashMap ;
import java.util.List ;
import java.util.ListIterator ;
import java.util.Map ;
import java.util.Map.Entry ;
import java.util.Queue ;
import java.util.concurrent.ConcurrentLinkedQueue ;
import java.util.concurrent.TimeUnit ;
@ -196,36 +196,12 @@ public class RedissonMultiLock implements Lock {
@Override
public boolean tryLock ( ) {
Map < RLock , RFuture < Boolean > > tryLockFutures = new HashMap < RLock , RFuture < Boolean > > ( locks . size ( ) ) ;
for ( RLock lock : locks ) {
tryLockFutures . put ( lock , lock . tryLockAsync ( ) ) ;
}
return sync ( tryLockFutures ) ;
}
protected boolean sync ( Map < RLock , RFuture < Boolean > > tryLockFutures ) {
List < RLock > lockedLocks = new ArrayList < RLock > ( tryLockFutures . size ( ) ) ;
RuntimeException latestException = null ;
for ( Entry < RLock , RFuture < Boolean > > entry : tryLockFutures . entrySet ( ) ) {
try {
if ( entry . getValue ( ) . syncUninterruptibly ( ) . getNow ( ) ) {
lockedLocks . add ( entry . getKey ( ) ) ;
}
} catch ( RuntimeException e ) {
latestException = e ;
}
}
if ( lockedLocks . size ( ) < tryLockFutures . size ( ) ) {
unlockInner ( lockedLocks ) ;
if ( latestException ! = null ) {
throw latestException ;
}
return tryLock ( - 1 , - 1 , null ) ;
} catch ( InterruptedException e ) {
Thread . currentThread ( ) . interrupt ( ) ;
return false ;
}
return true ;
}
protected void unlockInner ( Collection < RLock > locks ) {
@ -244,13 +220,70 @@ public class RedissonMultiLock implements Lock {
return tryLock ( waitTime , - 1 , unit ) ;
}
protected int failedLocksLimit ( ) {
return 0 ;
}
public boolean tryLock ( long waitTime , long leaseTime , TimeUnit unit ) throws InterruptedException {
Map < RLock , RFuture < Boolean > > tryLockFutures = new HashMap < RLock , RFuture < Boolean > > ( locks . size ( ) ) ;
for ( RLock lock : locks ) {
tryLockFutures . put ( lock , lock . tryLockAsync ( waitTime , leaseTime , unit ) ) ;
long newLeaseTime = - 1 ;
if ( leaseTime ! = - 1 ) {
newLeaseTime = waitTime * 2 ;
}
long time = System . currentTimeMillis ( ) ;
long remainTime = - 1 ;
if ( waitTime ! = - 1 ) {
remainTime = unit . toMillis ( waitTime ) ;
}
int failedLocksLimit = failedLocksLimit ( ) ;
List < RLock > lockedLocks = new ArrayList < RLock > ( locks . size ( ) ) ;
for ( ListIterator < RLock > iterator = locks . listIterator ( ) ; iterator . hasNext ( ) ; ) {
RLock lock = iterator . next ( ) ;
boolean lockAcquired ;
if ( waitTime = = - 1 & & leaseTime = = - 1 ) {
lockAcquired = lock . tryLock ( ) ;
} else {
lockAcquired = lock . tryLock ( unit . convert ( remainTime , TimeUnit . MILLISECONDS ) , newLeaseTime , unit ) ;
}
return sync ( tryLockFutures ) ;
if ( lockAcquired ) {
lockedLocks . add ( lock ) ;
} else {
if ( failedLocksLimit = = 0 ) {
unlockInner ( lockedLocks ) ;
if ( waitTime = = - 1 & & leaseTime = = - 1 ) {
return false ;
}
failedLocksLimit = failedLocksLimit ( ) ;
lockedLocks . clear ( ) ;
} else {
failedLocksLimit - - ;
}
}
if ( remainTime ! = - 1 ) {
remainTime - = ( System . currentTimeMillis ( ) - time ) ;
time = System . currentTimeMillis ( ) ;
if ( remainTime < 0 ) {
unlockInner ( lockedLocks ) ;
return false ;
}
}
}
if ( leaseTime ! = - 1 ) {
List < RFuture < Boolean > > futures = new ArrayList < RFuture < Boolean > > ( lockedLocks . size ( ) ) ;
for ( RLock rLock : lockedLocks ) {
RFuture < Boolean > future = rLock . expireAsync ( unit . toMillis ( leaseTime ) , TimeUnit . MILLISECONDS ) ;
futures . add ( future ) ;
}
for ( RFuture < Boolean > rFuture : futures ) {
rFuture . syncUninterruptibly ( ) ;
}
}
return true ;
}