您的位置:首页 > 其它

深入解析Hashtable的线程同步问题

2016-06-08 23:02 363 查看
在我们最熟悉的概念里,我们都知道相对于Hashmap而言,Hashtable的处理效率更慢,因为Hashtable引入了多线程安全机制,所以在处理键值对的时候,效率很慢。

但事实上Hashtable本身是没有实现serializable接口,也就是说它本身在多线程的机制中并不是线程安全的。

然而,在真正的应用开发上,当我们需要用到多线程的Hashtable时,我们都会在创建的时候引入同步概念,使得Hashtable变成线程安全的,详细代码解析如下:

class HashTableIsNot
{
private Hashtable a = new Hashtable();//不是线程安全的 
<span style="white-space:pre">	</span>/*因为Hashtable本身并不是线程同步,所以在直接创建Hasshtable对象时,它不再是线程安全的*/
private Hashtable b = Hashtable.Synchronized(new Hashtable());//线程安全的  
<span style="white-space:pre">	</span>/*只有在创建对象时引用了线程同步,才会使得创建出来的Hashtable对象变成线程安全*/
public void IsNotSafe()
{
Console.WriteLine("是否线程安全"+a.IsSynchronized);
Console.WriteLine("是否线程安全" + b.IsSynchronized);
// table1 = Hashtable.Synchronized(a);
Console.WriteLine("是否线程安全" + a.IsSynchronized);//
}

private void WriteA()
{
lock (a.SyncRoot)
{
Console.WriteLine("go  into  WriteA");
for (int i = 0; i < 10; i++)
{
a.Add(i, i);
Console.WriteLine(i);
Thread.Sleep(500);
}
Console.WriteLine("exit from  WriteA");
}
}
private void WriteB()
{
lock (table1.SyncRoot)
{
Console.WriteLine("go  into   WriteB");
for (int i = 10; i < 20; i++)
{
table1.Add(i, i);
Console.WriteLine(i);
Thread.Sleep(500);
}
Console.WriteLine("exit from  WriteB");
}
}
private void ReadA()
{
lock (a.SyncRoot)
{
Console.WriteLine("go  into   ReadA");
foreach (object a in A)
{
Console.WriteLine(a.ToString());
Thread.Sleep(500);
}
}
Console.WriteLine("exit from  ReadA");
}
public void SyncTest2()
{
Thread tWrite1 = new Thread(WriteA);
Thread tWrite2 = new Thread(WriteB);
Thread tRead1= new Thread(ReadA);
Thread tRead2 = new Thread(ReadB);
tWrite1.Start();
tRead2.Start();
tWrite2.Start();
tRead1.Start();
}
}

经过以上的例子,我们可以很明显的测试出,只有实现了serializable接口的Hashtable才能算作是线程安全。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息