<?phprequire
"vendor/autoload.php"
;
$client
=
new
Predis\Client([
'scheme'
=>
'tcp'
,
'host'
=>
'127.0.0.1'
,
'port'
=> 6379,]);
class
RedisLock{
public
$objRedis
= null;
public
$timeout
= 3;
public
function
__construct(
$obj
)
{
$this
->objRedis =
$obj
;
}
public
function
getLockCacheKey(
$key
)
{
return
"lock_{$key}"
;
}
public
function
getLock(
$key
,
$timeout
= NULL)
{
$timeout
=
$timeout
?
$timeout
:
$this
->timeout;
$lockCacheKey
=
$this
->getLockCacheKey(
$key
);
$expireAt
= time() +
$timeout
;
$isGet
= (bool)
$this
->objRedis->setnx(
$lockCacheKey
,
$expireAt
);
if
(
$isGet
) {
return
$expireAt
;
}
while
(1) { usleep(10);
$time
= time();
$oldExpire
=
$this
->objRedis->get(
$lockCacheKey
);
if
(
$oldExpire
>=
$time
) {
continue
;
}
$newExpire
=
$time
+
$timeout
;
$expireAt
=
$this
->objRedis->getset(
$lockCacheKey
,
$newExpire
);
if
(
$oldExpire
!=
$expireAt
) {
continue
;
}
$isGet
=
$newExpire
;
break
;
}
return
$isGet
;
}
public
function
releaseLock(
$key
,
$newExpire
)
{
$lockCacheKey
=
$this
->getLockCacheKey(
$key
);
if
(
$newExpire
>= time()) {
return
$this
->objRedis->del(
$lockCacheKey
);
}
return
true;
}
}
$start_time
= microtime(true);
$lock
=
new
RedisLock(
$client
);
$key
=
"name"
;
for
(
$i
= 0;
$i
< 10000;
$i
++) {
$newExpire
=
$lock
->getLock(
$key
);
$num
=
$client
->get(
$key
);
$num
++;
$client
->set(
$key
,
$num
);
$lock
->releaseLock(
$key
,
$newExpire
);}
$end_time
= microtime(true);
echo
"花费时间 : "
. (
$end_time
-
$start_time
) .
"\n"
;