这些私有静态成员是线程安全的吗
本文关键字:线程 安全 静态成员 | 更新日期: 2023-09-27 18:25:19
我有以下带有私有静态成员的代码。
所有这些类都表示,对于"publicstatic"成员,它们在MSDN库中是线程安全的。
我的问题是,当这些成员用作私有静态而不是MSDN库中所说的"公共静态"时,它们是否是线程安全的。
public static class passwordManager
{
private static System.Security.Cryptography.SHA256 shaM = new System.Security.Cryptography.SHA256Managed();
private static System.Security.Cryptography.RandomNumberGenerator rand = new System.Security.Cryptography.RNGCryptoServiceProvider();
private static System.Text.Encoding enc = System.Text.Encoding.ASCII;
public static string produceSalt(int size)
{
byte[] by = new byte[size];
lock (rand)
{
rand.GetBytes(by);
}
return enc.GetString(by, 0, by.Length);
}
public static string encryptPassword(string password, string salt){
return enc.GetString(shaM.ComputeHash(enc.GetBytes(password + salt)));
}
public static bool isCorrectPassword(string inputPassword, string DBsalt, string DBpassword)
{
return encryptPassword(inputPassword, DBsalt) == DBpassword;
}
这可能完全取决于我使用的方法本身是否使用共享变量,而不是所有方法实例变量。。。如果没有必要,我宁愿不把所有东西都锁在这里。
我锁定随机数生成器的唯一原因是限制获得相同salt的可能性,但在我的情况下,两个线程同时调用的可能性非常低。
谢谢,
Mike
这现在应该是线程安全的。我试图节省对象实例化开销,但我想这和锁等待之间有一个折衷。在高负载系统上,锁等待可能会大大超过实例化开销和内存使用。
public static class passwordManager
{
private static System.Security.Cryptography.RandomNumberGenerator rand = new System.Security.Cryptography.RNGCryptoServiceProvider();
public static byte[] produceSalt(int size)
{
byte[] by = new byte[size];
lock (rand)
{
rand.GetBytes(by);
}
return by;
}
public static byte[] encryptPassword(string password, byte[] salt){
System.Security.Cryptography.SHA256 shaM = new System.Security.Cryptography.SHA256Managed();
System.Text.Encoding enc = new System.Text.UTF8Encoding();
return shaM.ComputeHash(concatArrays(enc.GetBytes(password), salt));
}
public static bool isCorrectPassword(string inputPassword, byte[] DBsalt, byte[] DBpassword)
{
return compare(encryptPassword(inputPassword, DBsalt), DBpassword);
}
}
您的代码不是线程安全的。
考虑System.Text.Encoding
变量enc
。您正在调用作为实例成员的GetString
。文档指出,只有公共静态成员是线程安全的,因此推断GetString
不是线程安全的因为它不是公共静态成员1
此代码可能由于以下原因而失败:
- 您没有尝试同步对
Encoding.GetString
的访问 Encoding.GetString
是从passwordManager
类中的公共静态方法调用的- 公共静态方法同时被多个线程执行的概率很高
公共静态方法几乎总是被设计为线程安全的原因是,调用方总是同步对它的访问会很尴尬。你不能像对实例成员那样限制对静态成员的多线程访问。考虑一个ASP。NET应用程序。网页请求经常在单独的线程上同时处理。是否每次调用静态方法时都要使用lock
?当然不是。这对开发人员来说是一个荒谬的负担。
更新:
您的新代码现在是线程安全的。您必须进行一些基准测试,看看哪种方法更快:使用lock
或像现在这样在每次调用中实例化新实例。如果lock
更快,我不会感到惊讶。
对于CCD_ 11和CCD_。
线程安全性不取决于某个东西是私有的还是公共的。
顺便说一句,线程安全文档说这个类型的任何公共静态成员,而不是当这个类型被嵌入为公共静态时。
简而言之,如果你是多线程的,你必须像sham一样锁定你的字段。
您最好创建方法级变量,而不是尝试同步访问共享的私有字段。这样,您仍然可以实现并发性,因为每个线程都有自己的调用堆栈,因此每个对象都有单独的实例,从而允许多个线程同时执行该方法。如果锁定共享对象,那么一次只能有一个线程执行该方法。另一种选择可能是在每个字段上使用[ThreadStatic]属性,这样它们就不会在线程之间共享。