• .Net中多线程类的使用和总结


    lock, Monitor, Thread, Join, BackGroundWorker.   消费者和生产者。Async 委托Invoke

    TypeHandle中BlockIndex。

    http://msdn.microsoft.com/zh-cn/library/ms173179(v=vs.80).aspx

    a. lock相当于 Monitor.Enter, Monitor.Exit. 必须lock引用类型对象。

    不能lock公共对象,否则实例将超出代码的控制范围,容易引发死锁。 常见的结构 lock (this)lock (typeof (MyType)) 和 lock ("myLock") 违反此准则:

    对于一段代码锁住a,等待b,另一段代码锁住b,等待a,就会产生死锁

           lock(thisLock)
            {
                if (balance >= amount)
                {
                    Console.WriteLine("Balance before Withdrawal :  " + balance);
                    Console.WriteLine("Amount to Withdraw        : -" + amount);
                    balance = balance - amount;
                    Console.WriteLine("Balance after Withdrawal  :  " + balance);
                    return amount;
                }
                else
                {
                    return 0; // transaction rejected
                }
            }

    lock相当于如下:
    if(Monitor.TryEnter(m_inputQueue))
    {
        try
        {
             m_inputQueue.Enqueue(qValue);
        }
        finally
        {
         Monitor.Exit(m_inputQueue);
        }
    }
    Monitor.Enter(x);
    try {
        // Code that needs to be protected by the monitor.
    }
    finally {
        // Always use Finally to ensure that you exit the Monitor.
        // The following line creates another object containing 
        // the value of x, and throws SynchronizationLockException
        // because the two objects do not match.
        Monitor.Exit(x);
    }

    b. volatile关键字

    注意下面的private volatile bool _shouldStop; 加volatitle修饰后可以保证多个线程可以安全的访问此bool变量,这里的用bool表示状态是不需要同步的,并不是volatile保证了其原子性,
    而仅仅是因为他是个简单的bool型变量。votitle本身并不能保证绝对的原子性,如果volatile修饰的是复杂一些结构体,类对象,如果不使用线程同步,会产生非预期的中间状态数据。
    using System;
    using System.Threading;
    
    public class Worker
    {
        // This method will be called when the thread is started.
        public void DoWork()
        {
            while (!_shouldStop)
            {
                Console.WriteLine("worker thread: working...");
            }
            Console.WriteLine("worker thread: terminating gracefully.");
        }
        public void RequestStop()
        {
            _shouldStop = true;
        }
        // Volatile is used as hint to the compiler that this data
        // member will be accessed by multiple threads.
        private volatile bool _shouldStop;
    }
    
    public class WorkerThreadExample
    {
        static void Main()
        {
            // Create the thread object. This does not start the thread.
            Worker workerObject = new Worker();
            Thread workerThread = new Thread(workerObject.DoWork);
    
            // Start the worker thread.
            workerThread.Start();
            Console.WriteLine("main thread: Starting worker thread...");
    
            // Loop until worker thread activates.
            while (!workerThread.IsAlive);
    
            // Put the main thread to sleep for 1 millisecond to
            // allow the worker thread to do some work:
            Thread.Sleep(1);
    
            // Request that the worker thread stop itself:
            workerObject.RequestStop();
    
            // Use the Join method to block the current thread 
            // until the object's thread terminates.
            workerThread.Join();
            Console.WriteLine("main thread: Worker thread has terminated.");
        }
    }

    b. ManualResetEvent
    doneEvents[i] = new ManualResetEvent(false);
    
    // 1. Set event. Raise singal
    doneEvents[i].Set();
    
    // 2. Wait the signal until all the events raise the singal.
    WaitHandle.WaitAll(doneEvents);
    AutoResetEvent,


    c. ThreadPool线程池
    后台执行任务的线程集合,多用于服务器等需要多个线程的场合。为每个请求分配一个线程来执行请求,执行完请求后线程返回到队列等待再次被使用,
    避免了每个任务创建/销毁新线程的开销。如果请求过来之后没有可用的线程需要进队列排队。
    http://msdn.microsoft.com/zh-cn/library/3dasc8as(v=vs.90).aspx
    using System;
    using System.Threading;
    
    public class Fibonacci
    {
        public Fibonacci(int n, ManualResetEvent doneEvent)
        {
            _n = n;
            _doneEvent = doneEvent;
        }
    
        // Wrapper method for use with thread pool.
        public void ThreadPoolCallback(Object threadContext)
        {
            int threadIndex = (int)threadContext;
            Console.WriteLine("thread {0} started...", threadIndex);
            _fibOfN = Calculate(_n);
            Console.WriteLine("thread {0} result calculated...", threadIndex);
            _doneEvent.Set();
        }
    
        // Recursive method that calculates the Nth Fibonacci number.
        public int Calculate(int n)
        {
            if (n <= 1)
            {
                return n;
            }
    
            return Calculate(n - 1) + Calculate(n - 2);
        }
    
        public int N { get { return _n; } }
        private int _n;
    
        public int FibOfN { get { return _fibOfN; } }
        private int _fibOfN;
    
        private ManualResetEvent _doneEvent;
    }
    
    public class ThreadPoolExample
    {
        static void Main()
        {
            const int FibonacciCalculations = 10;
    
            // One event is used for each Fibonacci object
            ManualResetEvent[] doneEvents = new ManualResetEvent[FibonacciCalculations];
            Fibonacci[] fibArray = new Fibonacci[FibonacciCalculations];
            Random r = new Random();
    
            // Configure and launch threads using ThreadPool:
            Console.WriteLine("launching {0} tasks...", FibonacciCalculations);
            for (int i = 0; i < FibonacciCalculations; i++)
            {
                doneEvents[i] = new ManualResetEvent(false);
                Fibonacci f = new Fibonacci(r.Next(20,40), doneEvents[i]);
                fibArray[i] = f;
                ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);
            }
    
            // Wait for all threads in pool to calculation...
            WaitHandle.WaitAll(doneEvents);
            Console.WriteLine("All calculations are complete.");
    
            // Display the results...
            for (int i= 0; i<FibonacciCalculations; i++)
            {
                Fibonacci f = fibArray[i];
                Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN);
            }
        }
    }

    e. AutoResetEvent

  • 相关阅读:
    zip 中文文件夹为空问题
    webview长按文本区域不显示文字放大镜等方法
    crash
    精疲力尽先生的造访
    告别忙碌的2017,迎来更加忙碌的2018
    传说中的59分!!
    为什么我一定吵不过女人?
    人挪活!
    低谷时,请读书!
    java小入门的感觉
  • 原文地址:https://www.cnblogs.com/dirichlet/p/3252550.html
Copyright © 2020-2023  润新知