我需要一个身份验证令牌才能保证线程和同步安全。令牌将每小时到期,因此需要创建一个新令牌并将其分配给我的静态变量(TOKEN)
这会起作用吗?
谢谢,
public static volatile string TOKEN = string.Empty;
public static DateTime TOKEN_TIME = DateTime.Now;
private static readonly object syncRoot = new object();
public static string Get()
{
if (!string.IsNullOrEmpty(TOKEN))
{
if (!TokenIsValid())
{
lock(syncRoot)
TOKEN = CreateNewToken();
}
}
else
{
lock(syncRoot)
TOKEN = CreateNewToken();
}
return TOKEN;
}
答案 0 :(得分:4)
不,该代码不是线程安全的。由于锁定发生在if语句内部,因此两个线程可能几乎同时创建一个令牌。请考虑以下事项:
else
块else
块syncRoot
,创建新令牌(令牌A),并将其分配给TOKEN
syncRoot
,创建新令牌(令牌B),并将其分配给TOKEN
您的系统现在使用两个不同时间间隔创建的令牌,Thread
引用“令牌B”。
修改强>
在检查令牌之前,您可以通过锁定来使代码线程安全。下面的示例锁定了对Get()
的每次调用,因此它不会像代码一样(几乎)同时创建两个令牌。您还可以使用其他锁定模式,其中一些可能会提供更好的性能。
public static string Get()
{
lock(syncRoot)
{
if (string.IsNullOrEmpty(TOKEN) || !TokenIsValid())
TOKEN = CreateNewToken();
return TOKEN;
}
}