单例下并发的情况下访问私有变量的一个典型问题

一个小问题,单例下 并发的情况下访问私有变量的典型问题,以下是一个小Demo

public class dssd
    {
        static void Main(string[] args)
        {
            var t = Task.Factory.StartNew(() =>
            {
                Thread.Sleep(1000);
                var obj2 = ImportProvider.Instance;

                Arg ds = new Arg() { TypeSS = 2 };
                obj2.Import(ds);

            });

            var obj = ImportProvider.Instance;

            obj.Import(new Arg() { TypeSS = 1 });

            Console.Read();
        }
    }

    public interface IImportProvider
    {
        string Import(Arg args);
    }

    public class ImportProvider : IImportProvider
    {
        #region 单例
        public static readonly IImportProvider _instance = new ImportProvider();

        private ImportProvider() { }

        public static IImportProvider Instance { get { return _instance; } }
        #endregion

        public string Import(Arg args)
        {
            Yaya = new List<int>() { args.TypeSS };
            HSSFWorkbook workBook = new HSSFWorkbook() { dddd =args.TypeSS};

            if (args.TypeSS==1)
            {
                Thread.Sleep(5000);
                Console.WriteLine(Yaya[0]);
            }        

            return "ssss";
        }

        private List<int> Yaya = new List<int>();

    }

    public class HSSFWorkbook
    {
        public int dddd { get; set; }
    }

    public class Arg
    {
        public int TypeSS { get; set; }

    }

毫无疑问,第一个输出的 2,

因为在 Thread.Sleep(5000);

之后,Yaya[0]的值被 t线程走的代码给改了,这是单例下,私有变量遇到的一个常见的问题。在并发线程访问的情况下,她们是共享私有变量的,像上面这种情况,主线程中获取到了开启的工作线程改后变量值,问题典型,所以标一下
改后:

public class dssd
    {

        static void Main(string[] args)
        {
            List<int> Yaya = new List<int>();

            var t = Task.Factory.StartNew(() =>
            {
                Thread.Sleep(1000);
                var obj2 = ImportProvider.Instance;

                Arg ds = new Arg() { TypeSS = 2 };
                obj2.Import(ds, Yaya);

            });

            var obj = ImportProvider.Instance;

            obj.Import(new Arg() { TypeSS = 1 }, Yaya);                      

            Console.Read();
        }

    }

    public interface IImportProvider
    {
        string Import(Arg args, List<int> ww);
    }

    public class ImportProvider : IImportProvider
    {
        #region 单例
        public static readonly IImportProvider _instance = new ImportProvider();

        private ImportProvider() { }

        public static IImportProvider Instance { get { return _instance; } }
        #endregion

        public string Import(Arg args,List<int> ww)
        {
            ww = new List<int>() { args.TypeSS };
            HSSFWorkbook workBook = new HSSFWorkbook() { dddd =args.TypeSS};

            if (args.TypeSS==1)
            {
                Thread.Sleep(5000);
                Console.WriteLine(ww[0]);
            }        

            return "ssss";
        }

    }

    public class HSSFWorkbook
    {
        public int dddd { get; set; }
    }

    public class Arg
    {
        public int TypeSS { get; set; }

    }

输出:1

原文地址:https://www.cnblogs.com/wwkk/p/10321824.html

时间: 2024-10-13 15:38:25

单例下并发的情况下访问私有变量的一个典型问题的相关文章

Kafka在高并发的情况下,如何避免消息丢失和消息重复?kafka消费怎么保证数据消费一次?数据的一致性和统一性?数据的完整性?

1.kafka在高并发的情况下,如何避免消息丢失和消息重复? 消息丢失解决方案: 首先对kafka进行限速, 其次启用重试机制,重试间隔时间设置长一些,最后Kafka设置acks=all,即需要相应的所有处于ISR的分区都确认收到该消息后,才算发送成功 消息重复解决方案: 消息可以使用唯一id标识 生产者(ack=all 代表至少成功发送一次) 消费者 (offset手动提交,业务逻辑成功处理后,提交offset) 落表(主键或者唯一索引的方式,避免重复数据) 业务逻辑处理(选择唯一主键存储到R

@Component单例与并发

今天用websocket记录连接的个数: 模拟少量请求到服务器端的websocket,@Component默认是单例的,让其注解到MyWebSocket类上: 由于单例,每次请求过来都是相同的MyWebSocket对象,但是是不同的内存,修改其中之一对象的某些属性不会改变其他的对象的属性,可以使用static让多个连接请求共享变量的最终值,想要获得实时的值,让写操作与读同步就行. 错误的想法:把单例想象成了同一块内存了,多个请求被同一块内存处理. 应该是初始是被相同的对象处理,但是这些对象仅仅是

.net 反射访问私有变量和私有方法

以下为本次实践代码: 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Linq; 5 using System.Reflection; 6 using System.Text; 7 using System.Threading.Tasks; 8 9 namespace ConsoleTest 10 { 11 class Program 12 { 13

阿里Java面试题剖析:在高并发的情况下如何保证消息的顺序性?

面试原题 如何保证消息的顺序性? 面试官心理分析 其实这个也是用 MQ 的时候必问的话题,第一看看你了不了解顺序这个事儿?第二看看你有没有办法保证消息是有顺序的?这是生产系统中常见的问题. 面试题剖析 我举个例子,我们以前做过一个 mysql binlog 同步的系统,压力还是非常大的,日同步数据要达到上亿,就是说数据从一个 mysql 库原封不动地同步到另一个 mysql 库里面去(mysql -> mysql).常见的一点在于说比如大数据 team,就需要同步一个 mysql 库过来,对公司

高并发的情况下,如果处理大量请求修改同一样变量,用copy不用加锁。

modif_dict = {'name': None, 'age':None} 假如上面的数据是一个大量并发读取并修改的数据 modif_dicf['name'] = 'xiaom' modif_dict['age'] = 18 像上面这样的数据有大量的请求写入,为了防止高并发时数据重复写入,数据出现问题. 可以在前面添加 param = modif_dicy.copy() param['name'] = 'xiaobai' param['age'] = 20 如果从我的角度理解,因为使用了co

单例是个什么鬼

单例是个什么鬼 写在前面 常常听到有人说起单例,那么单例到底是什么呢?又该怎么用呢?或者说,它的应用场景有哪些呢?为了搞清楚这些问题,决定自己亲自实践一下,加深感悟.文中用到的一些单例的实现方式可能是从网上参考的,感谢大家的分享和讲解,这里就不一一引用啦. 单例是什么 单例,顾名思义,就是单个实例,也就是说,某个类如果实现了单例模式,那这个类就只能生成一个实例.单例模式是设计模式的一种,关于设计模式,我大概了解过有工厂模式,抽象工程模式,观察者模式,原型模式等,具体使用哪种设计模式,要视具体应用

Spring源码分析(二十四)初始化非延迟加载单例

摘要: 本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 完成BeanFactory的初始化工作,其中包括ConversionService的设置.配置冻结以及非延迟加载的bean的初始化工作. /** * Finish the initialization of this context's bean factory, * initializing all remaining singleton beans. */ protecte

多线程下真正的单例

首先,讨论一下单例对象的初始化同步.单例模式的通常处理方式是,在对象中有一个静态成员变量,其类型就是单例类型本身:如果该变量为null,则创建该单例类型的对象,并将该变量指向这个对象:如果该变量不为null,则直接使用该变量. 其过程如下面代码所示: Java代码 public class GlobalConfig { private static GlobalConfig instance = null; private Vector properties = null; private Gl

sql server中高并发情况下 同时执行select和update语句死锁问题 (一)

 最近在项目上线使用过程中使用SqlServer的时候发现在高并发情况下,频繁更新和频繁查询引发死锁.通常我们知道如果两个事务同时对一个表进行插入或修改数据,会发生在请求对表的X锁时,已经被对方持有了.由于得不到锁,后面的Commit无法执行,这样双方开始死锁.但是select语句和update语句同时执行,怎么会发生死锁呢?看完下面的分析,你会明白的- 首先看到代码中使用的查询的方法Select <span style="font-size:18px;"> /// &