public static ControladorUsuariosPorArea ObterInstancia()
        {
            // Aqui vem o segundo segredo da implementação, o Singleton tem o benefício de carregamento preguiçoso,
            // ou seja diferente das variáveis globais o singleton só cria a instancia quando é solicitado a primeira vez
            // só que em aplicações multi thread a solicitação da instancia inicial pode ocorrer em paralelo.
            // Então sem blocar o código verificamos se a instancia ainda está nula. Depois da 1 criação nunca vai entrar
            // nesse IF, mas sabemos que a primeira criação pode estar ocorrendo em paralelo.
            if (_instanciaUnica == null)
            {
                // Após entrar no if ai sim bloqueamos o objeto, para garantir a concorrência nesse trecho do código, ao invéz do paralelismo

                // ATENÇÃO!! RETIRE OS COMENTÁRIOS DA LINHA ABAIXO PARA VER O PROBLEMA SER RESOLVIDO
                //lock (_bloqueioSingleton)
                //{
                // Aqui fazemos a mesma verificação de novo, ai mesmo que passamos do primeiro if no caso da criação inicial paralela
                // não passaremos desse segundo, e não geraremos o problema
                if (_instanciaUnica == null)
                {
                    _instanciaUnica = new ControladorUsuariosPorArea();
                }
                //}
            }

            return(_instanciaUnica);
        }
예제 #2
0
        public void Executar()
        {
            var threads = new Thread[20];

            for (int i = 0; i < threads.Length; i++)
            {
                var i1 = i;
                threads[i] = new Thread(new ThreadStart(() => ControladorUsuariosPorArea.ObterInstancia().TentarAdicionarUsuarioArea($"João {i1}")));
            }

            foreach (var t in threads)
            {
                t.Start();
            }

            foreach (var t in threads)
            {
                t.Join();
            }

            ControladorUsuariosPorArea.ObterInstancia().ImprimirUsuarioNaArea();
        }