1. 程式人生 > >基於Tair 的分散式鎖

基於Tair 的分散式鎖

@Service("tairLockService")
@Slf4j
public class TairLockServiceImpl implements TairLockService {

    @Resource
    private MosTairLock mosTairLock;

    @Override
    public Boolean tryLockWait(String key, int secondsExpire, long millisTimeout) {
        if (StringUtil.isBlank(key)) {
            return false;
        }
        TairManager tairManager = mosTairLock.getTairManager();
        if (tairManager == null) {
            return false;
        }
        long deadTime = System.currentTimeMillis() + millisTimeout;
        while (System.currentTimeMillis() <= deadTime) {
            boolean lockResult = tryLock(key, secondsExpire,tairManager);
            if (lockResult) {
                return true;
            }
            try {
                long remainTimeout = deadTime - System.currentTimeMillis();
                if (remainTimeout <= 0) {
                    return false;
                }
                Thread.sleep(remainTimeout > 300 ? 300 : remainTimeout);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    @Override
    public void unLock(String key) {
        if (StringUtil.isBlank(key)) {
            return;
        }
        mosTairLock.getTairManager().invalid(TAIR_NAME_SPASE,key);
    }

    private String getLockValue() {
        try {
            InetAddress addr = InetAddress.getLocalHost();
            return addr.getHostName() + ":" + Thread.currentThread().getName();
        } catch (UnknownHostException e) {
            log.error("TairLockServiceImpl getLockValue system error" , e);
            return Thread.currentThread().getName();
        }
    }

    private boolean tryLock(String key, int secondsExpir,TairManager tairManager) {
        Result<DataEntry> result = tairManager.get(TAIR_NAME_SPASE, key);
        if (result == null) {
            return false;
        }
        if (ResultCode.DATANOTEXSITS.equals(result.getRc())) {
            ResultCode code = tairManager.put(TAIR_NAME_SPASE, key, getLockValue(), 2, secondsExpir);
            if (ResultCode.SUCCESS.equals(code))
                return true;
        } else if (result.getValue() != null && getLockValue().equals(result.getValue().getValue())) {
            return true;
        }
        return false;
    }

}