zoukankan      html  css  js  c++  java
  • 线程安全 二

    using System;
    using System.Threading;

    abstract class Counter
    {
        protected int count = 0;

        public abstract int Read(int threadNum);
        public abstract void Increment(int threadNum); 
    }

    // Note that the instance variable count is shared between the two methods Read
    // and Increment. Threads concurrently executing one or both of these methods can
    // interfere with each other unless action is taken to synchronize access

    class CounterUnsafe : Counter
    {
        public override int Read(int threadNum) 
        {
            // following code is not thread-safe and has a race condition
            try 
            {
                Console.WriteLine(
                    "Start Resource reading (Thread={0})count: {1}", threadNum, count);
                Thread.Sleep(250);
                Console.WriteLine(
                    "Stop  Resource reading (Thread={0}) count: {1}", threadNum, count);
                return count;
            }
            finally 
            {
            }
        }

        public override void Increment(int threadNum) 
        {
            // following code is not thread-safe and has a race condition
            try 
            {
                Console.WriteLine(
                    "Start Resource writing (Thread={0}) count: {1}", threadNum, count);
                // the following four lines simulate count++ with a very large
                
    // window of time between count being read and being incremented.
                
    // This large window ensures that the race condition will create
                
    // errors often when the code is accessed concurrently by multiple threads.
                int tempCount = count;
                Thread.Sleep(1000);
                tempCount++;
                count = tempCount;
                Console.WriteLine(
                    "Stop  Resource writing (Thread={0}) count: {1}", threadNum, count);
            }
            finally 
            {
            }
        }
    }

    class CounterUsingInterlocked : Counter
    {
        public override int Read(int threadNum) 
        {
            try 
            {
                // following is thread safe but since Increments can occur during
                
    //  this method, the value of count can change between the start 
                
    //  of the method and its return/end, if this is a problem
                
    //  you need to use manual locks or a synchronized context.
                Console.WriteLine(
                    "Start Resource reading (Thread={0})count: {1}", threadNum, count);
                Thread.Sleep(250);
                Console.WriteLine(
                    "Stop  Resource reading (Thread={0}) count: {1}", threadNum, count);
                return count;
            }
            finally 
            {
            }
        }

        public override void Increment(int threadNum) 
        {
            // ...
            
    // method code that doesn't require exclusive access 
            try 
            {
                Console.WriteLine(
                    "Start Resource writing (Thread={0}) count: {1}", threadNum, count);
                // Note that count++ is not  an atomic operation and therefore not thread-safe.
                
    //  With count++ there would be a window of time between reading the value count and 
                
    //  incrementing the value of count during which time another thread could execute and
                
    //  also read and/or change the value of count. Even thought this window
                
    //  is much smaller than with the CounterUnsafe methods this non atomic operation
                
    //  still results in a race condition where an increment can be lost.
                
    // To make the increment of count thread-safe we use an atomic Interlocked.Increment call.
                int tempCount = Interlocked.Increment(ref count);
                Console.WriteLine(
                    "Stop Resource writing (Thread={0}) count: {1}", threadNum, tempCount);
            }
            finally 
            {
            }
        }
    }

    class CounterUsingLock : Counter
    {
        public override int Read(int threadNum) 
        {
            // ...
            
    // method code that doesn't require exclusive access 
            lock(this)
            {
                Console.WriteLine(
                    "Start Resource reading (Thread={0})count: {1}", threadNum, count);
                Thread.Sleep(250);
                Console.WriteLine(
                    "Stop Resource reading (Thread={0}) count: {1}", threadNum, count);
                return count;
            }
        }

        public override void Increment(int threadNum) 
        {
            // ...
            
    // method code that doesn't require exclusive access 
            lock(this)
            {
                Console.WriteLine(
                    "Start Resource writing (Thread={0}) count: {1}", threadNum, count);
                int tempCount = count;
                Thread.Sleep(1000);
                tempCount++;
                count = tempCount;
                Console.WriteLine(
                    "Stop Resource writing (Thread={0}) count: {1}", threadNum, count);
            }
            // rest of method code that doesn't require exclusive access
        }
    }

    class CounterUsingMutex : Counter
    {
        Mutex m = new Mutex(); 

        public override int Read(int threadNum) 
        {
            // ...
            
    // method code that doesn't require exclusive access 
            m.WaitOne();
            try 
            {
                Console.WriteLine(
                    "Start Resource reading (Thread={0})count: {1}", threadNum, count);
                Thread.Sleep(250);
                Console.WriteLine(
                    "Stop Resource reading (Thread={0}) count: {1}", threadNum, count);
                return count;
            }
            finally 
            {
                m.ReleaseMutex();
            }
        }

        public override void Increment(int threadNum) 
        {
            // ...
            
    // method code that doesn't require exclusive access 
            m.WaitOne();
            try 
            {
                Console.WriteLine(
                    "Start Resource writing (Thread={0}) count: {1}", threadNum, count);
                int tempCount = count;
                Thread.Sleep(1000);
                tempCount++;
                count = tempCount;
                Console.WriteLine(
                    "Stop Resource writing (Thread={0}) count: {1}", threadNum, count);
            }
            finally 
            {
                m.ReleaseMutex();
            }
            // rest of method code that doesn't require exclusive access
        }
    }

    class CounterUsingReaderWriterLock : Counter
    {
        ReaderWriterLock rwl = new ReaderWriterLock();

        public override int Read(int threadNum) 
        {
            // ...
            
    // method code that doesn't require exclusive access 
            rwl.AcquireReaderLock(Timeout.Infinite);
            try 
            {
                Console.WriteLine(
                 "Start Resource reading (Thread={0})count: {1}", threadNum, count);
                Thread.Sleep(250);
                Console.WriteLine(
                 "Stop Resource reading (Thread={0}) count: {1}", threadNum, count);
                return count;
            }
            finally 
            {
                rwl.ReleaseReaderLock();
            }
        }

        public override void Increment(int threadNum) 
        {
            // ...
            
    // method code that doesn't require exclusive access 
            rwl.AcquireWriterLock(Timeout.Infinite);
            try 
            {
                Console.WriteLine(
                 "Start Resource writing (Thread={0}) count: {1}", threadNum, count);
                int tempCount = count;
                Thread.Sleep(1000);
                tempCount++;
                count = tempCount;
                Console.WriteLine(
                 "Stop  Resource writing (Thread={0}) count: {1}", threadNum, count);
            }
            finally 
            {
                rwl.ReleaseWriterLock();
            }
            // rest of method code that doesn't require exclusive access
        }
    }


    class App 
    {
        static Counter counter = null;
        static int totalNumberOfAsyncOps = 10;
        static int numAsyncOps = totalNumberOfAsyncOps;
        static AutoResetEvent asyncOpsAreDone = new AutoResetEvent(false);

        public static void Main() 
        {
            Console.WriteLine("\n\nUnsafe test:");
            asyncOpsAreDone.Reset();
            numAsyncOps = totalNumberOfAsyncOps;
            counter = new CounterUnsafe();
            for (int threadNum = 0; threadNum < numAsyncOps; threadNum++) 
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateResource), threadNum);
            }
            asyncOpsAreDone.WaitOne();
            Console.WriteLine("All Unsafe threads have completed.");
            
            
            Console.WriteLine("\n\nInterlocked test:");
            asyncOpsAreDone.Reset();
            numAsyncOps = totalNumberOfAsyncOps;
            counter = new CounterUsingInterlocked();
            for (int threadNum = 0; threadNum < totalNumberOfAsyncOps; threadNum++) 
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateResource), threadNum);
            }
            asyncOpsAreDone.WaitOne();
            Console.WriteLine("All Interlocked threads have completed.");


            Console.WriteLine("\n\nLock test:");
            asyncOpsAreDone.Reset();
            numAsyncOps = totalNumberOfAsyncOps;
            counter = new CounterUsingLock();
            for (int threadNum = 0; threadNum < numAsyncOps; threadNum++) 
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateResource), threadNum);
            }
            asyncOpsAreDone.WaitOne();
            Console.WriteLine("All Lock threads have completed.");

            Console.WriteLine("\n\nMutex test:");
            asyncOpsAreDone.Reset();
            numAsyncOps = totalNumberOfAsyncOps;
            counter = new CounterUsingMutex();
            for (int threadNum = 0; threadNum < numAsyncOps; threadNum++) 
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateResource), threadNum);
            }
            asyncOpsAreDone.WaitOne();
            Console.WriteLine("All Mutex threads have completed.");

        
            asyncOpsAreDone.Reset();
            numAsyncOps = totalNumberOfAsyncOps;
            counter = new CounterUsingReaderWriterLock();
            Console.WriteLine("\n\nReadWriteLock test:");
            for (int threadNum = 0; threadNum < numAsyncOps; threadNum++) 
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateResource), threadNum);
            }
            asyncOpsAreDone.WaitOne();
            Console.WriteLine("All ReadWriteLock threads have completed.");
            
        }


        // The callback method's signature MUST match that of a System.Threading.TimerCallback 
        
    // delegate (it takes an Object parameter and returns void)
        static void UpdateResource(Object state) 
        {
            int threadNum = (int) state;
            if ((threadNum % 2) != 0) counter.Read(threadNum);
            else counter.Increment(threadNum);

            if (( Interlocked.Decrement(ref numAsyncOps)) == 0)
                asyncOpsAreDone.Set();
        }
    }
  • 相关阅读:
    市面上的系统.
    linux /dev 常见特殊设备介绍与应用[loop,null,zero,full,random]
    Linux command 系统快捷键
    Qtcreator中常用快捷键总结
    开始新的博客征途
    css选择器顺序的小技巧
    推荐20个很有帮助的web前端开发教程
    炙手可热的前端资源大集合
    一款纯css实现的垂直时间线效果
    15款极具创造性的艺术创意
  • 原文地址:https://www.cnblogs.com/imxh/p/2249526.html
Copyright © 2011-2022 走看看