Пример #1
0
        static void Ex12()
        {
            //same Bank that
            //can Transfer an amount from a source BankAccount
            //to a target BankAccount.

            //if multiple threads try to transfer from the same
            //accounts, concurrency problems could arise....

            ExampleLibrary.BankScenario.BankAccount ba1 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 1
            };
            ExampleLibrary.BankScenario.BankAccount ba2 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 2
            };

            ba1.Deposit(100);

            ExampleLibrary.BankScenario.NotSynchronized.Bank bank = new ExampleLibrary.BankScenario.NotSynchronized.Bank();
            for (int i = 0; i < 100; i++)   //200 concurrent Threads running transfer
            {
                new Thread(() => {
                    bank.Transfer(ba1, ba2, 50);
                    Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}");
                }).Start();
                new Thread(() => {
                    bank.Transfer(ba2, ba1, 50);
                    Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}");
                }).Start();
            }
            //we could see weird numbers popping up....
        }
Пример #2
0
        static void Ex11()
        {
            //in our scenario we have a Bank that
            //can Transfer an amount from a source BankAccount
            //to a target BankAccount.

            //if we do not use multithreading,
            //no problems will arise

            ExampleLibrary.BankScenario.BankAccount ba1 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 1
            };
            ExampleLibrary.BankScenario.BankAccount ba2 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 2
            };

            ba1.Deposit(100);

            ExampleLibrary.BankScenario.NotSynchronized.Bank bank = new ExampleLibrary.BankScenario.NotSynchronized.Bank();
            for (int i = 0; i < 100; i++)   //200 transfer
            {
                bank.Transfer(ba1, ba2, 50);
                bank.Transfer(ba2, ba1, 50);
            }
            Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}"); //ba1.Saldo == 100, ba2.Saldo == 0
        }
Пример #3
0
        static void Ex15()
        {
            //this Bank has an Event it's waiting for
            //in order to proceed with the Transfer.

            ExampleLibrary.BankScenario.BankAccount ba1 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 1
            };
            ExampleLibrary.BankScenario.BankAccount ba2 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 2
            };

            ba1.Deposit(100);

            ExampleLibrary.BankScenario.EventWaitHandles.Bank bank = new ExampleLibrary.BankScenario.EventWaitHandles.Bank();
            for (int i = 0; i < 100; i++)   //200 concurrent Threads running transfer
            {
                new Thread(() => {
                    bank.Transfer(ba1, ba2, 50);
                    Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}");
                }).Start();
                new Thread(() => {
                    bank.Transfer(ba2, ba1, 50);
                    Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}");
                }).Start();
            }
        }
Пример #4
0
        static void Ex13()
        {
            //this Bank locks the bankAccounts it wants to use
            //when Transfering an amount from a source BankAccount
            //to a target BankAccount.

            //if multiple threads try to transfer from the same
            //accounts, deadlock problems could arise....

            ExampleLibrary.BankScenario.BankAccount ba1 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 1
            };
            ExampleLibrary.BankScenario.BankAccount ba2 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 2
            };

            ba1.Deposit(100);

            ExampleLibrary.BankScenario.Deadlocked.Bank bank = new ExampleLibrary.BankScenario.Deadlocked.Bank();
            for (int i = 0; i < 100; i++)   //200 concurrent Threads running transfer
            {
                new Thread(() => {
                    bank.Transfer(ba1, ba2, 50);
                    Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}");
                }).Start();
                new Thread(() => {
                    bank.Transfer(ba2, ba1, 50);
                    Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}");
                }).Start();
            }
            //we could never get here....
        }
Пример #5
0
        static void Ex03()
        {
            //This example is equivalent to Ex15 of the Thread examples,
            //but it's faster because it does not spawn 200 new Threads
            //and it uses the ThreadPool instead.

            ExampleLibrary.BankScenario.BankAccount ba1 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 1
            };
            ExampleLibrary.BankScenario.BankAccount ba2 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 2
            };

            ba1.Deposit(100);

            ExampleLibrary.BankScenario.EventWaitHandles.Bank bank = new ExampleLibrary.BankScenario.EventWaitHandles.Bank();
            for (int i = 0; i < 100; i++)   //200 concurrent Threads running transfer
            {
                ThreadPool.QueueUserWorkItem(_ => {
                    bank.Transfer(ba1, ba2, 50);
                    Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}");
                });
                ThreadPool.QueueUserWorkItem(_ => {
                    bank.Transfer(ba2, ba1, 50);
                    Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}");
                });
            }
        }
Пример #6
0
        static void Ex17()
        {
            //In this scenario we want to wait for all Thread to finish
            //before we continue.
            //Another thing we could do is to create just one event
            //and set it when a counter reaches 200.
            //BUT we have to increase the same counter on 200 different threads,
            //meaning that we have to do it in a thread safe manner.

            AutoResetEvent doneEvent = new AutoResetEvent(false);

            ExampleLibrary.BankScenario.BankAccount ba1 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 1
            };
            ExampleLibrary.BankScenario.BankAccount ba2 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 2
            };

            ba1.Deposit(100);

            ExampleLibrary.BankScenario.EventWaitHandles.Bank bank = new ExampleLibrary.BankScenario.EventWaitHandles.Bank();
            int counter = 0;

            for (int i = 0; i < 100; i++)   //200 concurrent Threads running transfer
            {
                new Thread(() => {
                    bank.Transfer(ba1, ba2, 50);
                    Interlocked.Increment(ref counter);
                    Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}");
                    if (counter == 200)
                    {
                        doneEvent.Set();
                    }
                }).Start();
                new Thread(() => {
                    bank.Transfer(ba2, ba1, 50);
                    Interlocked.Increment(ref counter);
                    Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}");
                    if (counter == 200)
                    {
                        doneEvent.Set();
                    }
                }).Start();
            }
            doneEvent.WaitOne();
            Console.WriteLine("DONE!!");
        }
Пример #7
0
        static void Ex14()
        {
            //this Bank tries to lock the bankAccounts it wants to use
            //for 10 milliseconds, after which it stops trying.
            //that's why this transfer could fail.

            //if multiple threads try to transfer from the same
            //accounts, the transfer could fail,
            //so we can decide if we want to keep trying,
            //or stop, or who knows what

            ExampleLibrary.BankScenario.BankAccount ba1 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 1
            };
            ExampleLibrary.BankScenario.BankAccount ba2 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 2
            };

            ba1.Deposit(100);

            ExampleLibrary.BankScenario.Timeout.Bank bank = new ExampleLibrary.BankScenario.Timeout.Bank();
            for (int i = 0; i < 100; i++)   //200 concurrent Threads running transfer
            {
                new Thread(() => {
                    while (!bank.Transfer(ba1, ba2, 50))   //it could timeout
                    {
                        Console.Write(".");
                    } //keep trying until we get it
                    Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}");
                }).Start();
                new Thread(() => {
                    while (!bank.Transfer(ba2, ba1, 50))   //it could timeout
                    {
                        Console.Write(".");
                    } //keep trying until we get it
                    Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}");
                }).Start();
            }
        }
Пример #8
0
        static void Ex16()
        {
            //In this scenario we want to wait for all Thread to finish
            //before we continue.
            //We could create 200 AutoResetEvents, put them in an Array,
            //signal each one of them from a Thread
            //and use EventWaitHandle.WaitAll,
            //but they would be too many.

            AutoResetEvent[] events = Enumerable.Repeat(new AutoResetEvent(false), 200).ToArray();

            ExampleLibrary.BankScenario.BankAccount ba1 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 1
            };
            ExampleLibrary.BankScenario.BankAccount ba2 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 2
            };

            ba1.Deposit(100);

            ExampleLibrary.BankScenario.EventWaitHandles.Bank bank = new ExampleLibrary.BankScenario.EventWaitHandles.Bank();
            for (int i = 0; i < 100; i++)   //200 concurrent Threads running transfer
            {
                new Thread(() => {
                    bank.Transfer(ba1, ba2, 50);
                    events[i].Set();
                    Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}");
                }).Start();
                new Thread(() => {
                    bank.Transfer(ba2, ba1, 50);
                    events[i + 100].Set();
                    Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}");
                }).Start();
            }
            //boom!
            WaitHandle.WaitAll(events);
            Console.WriteLine("DONE!!");
        }
Пример #9
0
        static void Ex18()
        {
            //In this scenario we want to wait for all Thread to finish
            //before we continue.
            //Another thing we could do is to use a CountdownEvent.

            CountdownEvent doneEvent = new CountdownEvent(200);

            ExampleLibrary.BankScenario.BankAccount ba1 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 1
            };
            ExampleLibrary.BankScenario.BankAccount ba2 = new ExampleLibrary.BankScenario.BankAccount()
            {
                Id = 2
            };

            ba1.Deposit(100);

            ExampleLibrary.BankScenario.EventWaitHandles.Bank bank = new ExampleLibrary.BankScenario.EventWaitHandles.Bank();
            for (int i = 0; i < 100; i++)   //200 concurrent Threads running transfer
            {
                new Thread(() => {
                    bank.Transfer(ba1, ba2, 50);
                    Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}");
                    doneEvent.Signal();
                }).Start();
                new Thread(() => {
                    bank.Transfer(ba2, ba1, 50);
                    Console.WriteLine($"{ba1.Id} == {ba1.Saldo}\t{ba2.Id} == {ba2.Saldo}");
                    doneEvent.Signal();
                }).Start();
            }
            doneEvent.Wait(); //waiting for it to reach 0
            Console.WriteLine("DONE!!");
        }