序列化是线程安全的么

因为最近开始学习使用WCF,而WCF的一大特点就是传输数据前,进行序列化。

于是会出现多个线程同时序列化一个对象,于是开始思考,序列化是线程安全的么。

去查看MSDN,被告知:

此类型的任何公共静态(Visual Basic 中的Shared)成员都是线程安全的,但不保证所有实例成员都是线程安全的。

http://msdn.microsoft.com/zh-cn/library/y50tb888(v=vs.100).aspx

假设对象是一个普通的类,我们开4个线程对其属性进行不断的设置,同时开设一个线程进行序列化。

Student s = new Student();
            Task t = new Task(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    s.ads2 = string.Format("task1{0}", i);
                    Thread.Sleep(100);
                }
            }
            );
            Task t2 = new Task(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    s.ads3 = string.Format("task2{0}", i);
                    Thread.Sleep(100);
                }
            });
            Task t3 = new Task(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    s.Name = string.Format("task3name{0}", i);
                    Thread.Sleep(100);
                }
            }
                );
            Task t4 = new Task(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    s.Adtress = string.Format("task4{0}", i);
                    Thread.Sleep(100);
                }
            });
            Task t5 = new Task(() =>
            {
                try
                {
                    for (int i = 0; i < 100; i++)
                    {
                        using (FileStream filestream = new FileStream(@"D:\data\123.txt", FileMode.OpenOrCreate))
                        {
                            BinaryFormatter bf = new BinaryFormatter();
                            bf.Serialize(filestream, s);

                        }
                        Thread.Sleep(100);
                        Console.WriteLine("Serilize Success {0}", i);
                        using (FileStream fs = new FileStream(@"D:\data\123.txt", FileMode.OpenOrCreate))
                        {
                            BinaryFormatter b = new BinaryFormatter();
                            Student s1 = b.Deserialize(fs) as Student;
                            Console.WriteLine(s1.ToString());
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Erro{0}", ex);
                }
            });
            Console.WriteLine("Start");
            t.Start();
            t2.Start();
            t3.Start();
            t4.Start();
            t5.Start();
            Console.ReadLine();

运行结果,没有异常,线程安全

实验2,如果对象是一个集合类呢?开启2个线程不断的进行add或者remove(因为我需要的场景只需要add,所以只进行add验证),同时再开启2个线程同时进行序列化

  List<Student> ss = new List<Student>();
            Task t1 = new Task(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    lock (ss)
                    {
                        ss.Add(new Student());
                        Thread.Sleep(100);
                    }
                }
            });
            Task t4 = new Task(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    lock (ss)
                    {
                        ss.Add(new Student());
                        Thread.Sleep(103);
                    }
                }
            });
            Task t2 = new Task(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    using (FileStream fs = new FileStream(@"D:\data\234.txt", FileMode.OpenOrCreate))
                    {
                        BinaryFormatter bf = new BinaryFormatter();
                        bf.Serialize(fs, ss);
                        Console.WriteLine("Serilize1 ss count{0}", ss.Count);
                        Console.WriteLine("Serilize1 Done");
                        Thread.Sleep(101);
                    }
                }
            });
            Task t3 = new Task(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    using (FileStream fs = new FileStream(@"D:\data\345.txt", FileMode.OpenOrCreate))
                    {
                        BinaryFormatter bf = new BinaryFormatter();
                        bf.Serialize(fs, ss);
                        Console.WriteLine("Serilize2 ss count{0}", ss.Count);
                        Console.WriteLine("Serilize2 Done");
                        Thread.Sleep(102);
                    }
                }
            });
            Console.WriteLine("Start");
            t1.Start();
            t2.Start();
            t3.Start();
            t4.Start();
            Console.ReadLine();

运行结果是线程安全。

结论是在多线程场景下,多个线程对同一对象进行序列化时,即使同时对象本身属性在不断被修改,或者同时进行add操作或remove操作,也是线程安全的。

原文地址:https://www.cnblogs.com/suriyel/p/2717649.html