在我们最熟悉的概念里,我们都知道相对于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();
- }
- }