上一篇大家已经知道了,线程与线程之间的调度,是不可控的,那当我们去写多线程程序的时候,一定要将线程是乱序的这一点考虑进去,若不然就会出现线程安全问题。 为什么这样讲呢?因为当程序出现多个线程在运行的时候,你无法确定到底是哪一个线程在执行,可能A执行一行代码,这个时候 ...
上一篇大家已经知道了,get='_blank'>线程与线程之间的调度,是不可控的,那当我们去写多线程程序的时候,一定要将线程是乱序的这一点考虑进去,若不然就会出现线程安全问题。
为什么这样讲呢?因为当程序出现多个线程在运行的时候,你无法确定到底是哪一个线程在执行,可能A执行一行代码,这个时候切换到B执行一行代码,然后又切换回A再执行一行代码,这都是有可能出现,不要以为我的代码短,就那么一两行就不需要上锁,多线程程序一定要严谨。
那如何保证严谨呢?
就是当你的程序在使用共享资源的时候,就是当多个线程都有可能调用到同一个变量或是访问同一块内存的时候,一定要保证这段代码的线性执行,比如我有以下代码:
public class DbActionQueue : IDisposable { public Queue<Action> _transQueue; private Thread _thread; private bool _isDispose = false; private static readonly object _syncObject = new object(); private readonly object _syncQueueObject = new object(); private static DbActionQueue _instance; public static DbActionQueue Instance { get { if (_instance == null) { lock (_syncObject) { if (_instance == null) { _instance = new DbActionQueue(); } } } return _instance; } } private DbActionQueue() { if (_transQueue == null) { _transQueue = new Queue<Action>(); } if (_thread == null) { _thread = new Thread(Thread_Work) { IsBackground = true }; } _thread.Start(); } public void Push(Action action) { if (_transQueue == null) throw new ArgumentNullException("dbActionQueue is not init"); lock (_syncQueueObject) { _transQueue.Enqueue(action); } } public void Thread_Work() { while (!_isDispose) { Action[] items = null; if (_transQueue != null && _transQueue.Count > 0) { lock (_syncQueueObject) { items = new Action[_transQueue.Count]; _transQueue.CopyTo(items, 0); _transQueue.Clear(); } } if (items != null && items.Length > 0) { foreach (var item in items) { try { item.Invoke(); } catch (Exception ex) { LogHelper.Write(string.Format("DbActionQueue error. | Exception.StackTrace:{0}", ex.StackTrace), ex); } } } Thread.Sleep(1); } } public void Dispose() { _isDispose = true; _thread.Join(); } }
原标题:自以为是的多线程(二)
关键词:线程
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。