• 序列化是线程安全的么


    因为最近开始学习使用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操作,也是线程安全的。

  • 相关阅读:
    easyui combobox 实现联动
    smartWizard 和 uploadify 插件
    easyui panel href 引用页面导致的命名冲突问题
    Installshield 多语言安装包 和 安装序列号验证,及如何解决 Failed to set code page for Language 46 问题
    easyui 之tab和portal 在IE9下使用iframe时报未定义错误的解决方法
    easyui datagrid 动态列和前端分页,以及加载Datatable
    easyui 动态创建模式对话框
    移动硬盘一个分区“数据循环冗余错误”要求格式化解决方法
    easyui 开发中的通用类库
    easyui datagrid 工具栏实现方式
  • 原文地址:https://www.cnblogs.com/suriyel/p/2717649.html
Copyright © 2020-2023  润新知