<?php
namespace Lock;
/**
 * User: liuyuzhen
 * Date: 2018/8/20
 * Time: 10:48
 * Description:
 */
class RedisLock implements \Lock\ILock{

    private $lockRedis ;
    public function __construct()
    {

        $this->lockRedis = \Redis\Db1\LockRedisModel::getInstance();
    }

    public function getMicrotime(){
        list($msec, $sec) = explode(' ', microtime());
        $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
        return $msectime;
    }

    public function getLock($key, $timeout=self::EXPIRE)
    {

        $currMicroTime = $this->getMicrotime();
        $is_lock = $this->lockRedis->tableSetnx($key, $currMicroTime+10);
        $i = 0;
        while($is_lock==false&&$i<3){
            $is_lock = $this->lockRedis->tableSetnx($key, $currMicroTime+10);
            $i++;
        }
        // 不能获取锁
        if(!$is_lock){
            //判断锁是否过期
            $lock_time = $this->lockRedis->tableCacheGet($key);
            // 锁已过期，删除锁，重新获取
            if($currMicroTime>(float)$lock_time){
                $this->releaseLock($key);
                $is_lock = $this->lockRedis->tableSetnx($key, $currMicroTime+$timeout);
            }
        }
        return $is_lock? true : false;
    }

    public function releaseLock($key)
    {
        $this->lockRedis->tableDel($key);
    }

    /**
     * 类实例
     *
     */
    private static $_instance = null;

    /**
     * 获取类实例
     */
    public static function getInstance() {
        if (!(self::$_instance instanceof self)) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }
}