zoukankan      html  css  js  c++  java
  • 序列化是线程安全的么

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

  • 相关阅读:
    FindBugs详解
    Java杂项
    Ubuntu 16.04安装DB2 Express C v11.1
    h5搜索功能
    与安卓交互的上传图片 与 上传语音、视频
    获取后台轮播图图片,让其自动播放
    点赞和关注功能
    split、replace、indexof、substr 用法 (获取后台富文本框内容,截取图片)
    ttyu平台进页面获取阅读量
    图片放大预览功能
  • 原文地址:https://www.cnblogs.com/suriyel/p/2717649.html
Copyright © 2011-2022 走看看