zoukankan      html  css  js  c++  java
  • 多线程随笔

    一、前言

      很久没有更新blog了,太忙了,都没时间来整理一下知识点,年底了有点时间了,可以好好整理以前写的项目代码了,顺便把常用的业务方法都封装成通用的方法,以便以后使用到能快速完成。切入主题,封装了一个常用的多线程使用场景的类库,提供两种模式,跟大家分享。

    二、并发模式

      很多时候,我们会遇到这种情况,事件A和事件B毫无关系,是两个很耗时的相对独立事件,但是事件C需要用到事件A、B完成之后的结果。如下图,假设,我们的目的是建造一栋房子,事件A表示去拉砖头,事件B表示去找工人,事件C表示开始建房,

     

    步骤代码片段:

    static void Main(string[] args)
            {
                ThreadWRR.Init(ThreadWRR.RunningType.Concurrent);
                ThreadWRR.AddTask(Test1, "A");
                ThreadWRR.AddTask(Test2, "B");
                //ThreadWRR.AddTask(Test3, null);
                ThreadWRR.Start();
                
                while (ThreadWRR.IsRunning)
                {
                    Console.WriteLine("C:在A、B完成之前,可以干一些活...");
                }
                Console.WriteLine("C:那开始建房吧!!!");
                Console.ReadKey();
            }
    
            static void Test1(object s)
            {
                Console.WriteLine(s + "正在去搬砖...");
                for (int i = 1; i <= 5; i++)
                {
                    Console.WriteLine(s.ToString() +" 运送"+ i+"车...");
                    Thread.Sleep(500);
                }
                Console.WriteLine(s + "搬完砖了!");
            }
    
            static void Test2(object s)
            {
                Console.WriteLine(s + "正在去找工人...");
                int ipeople = 0;
                for (int i = 1; i <= 5; i++)
                {
                    ipeople += i * 5;
                    Console.WriteLine(s.ToString() + " 找到" + ipeople + "个工人...");
                    Thread.Sleep(500);
                }
                Console.WriteLine(s + "找够人了!");
            }

      

    二、顺序模式

      另一种情况,事件B必须等事件A的结果,才能进行下一步任务的进行,C则等待AB都完成之后开始下一步任务,如图,假设,事件A表示组装电脑,事件B表示等A组装好之后进行打包工作,事件C表示装车去配送,C在AB过程中可以做一些事件,比如去拿车,去加油等等,总之do something。

    步骤代码片段:

    static void Main(string[] args)
            {
                ThreadWRR.Init(ThreadWRR.RunningType.Order);
                ThreadWRR.AddTask(Test1, "A");
                ThreadWRR.AddTask(Test2, "B");
                //ThreadWRR.AddTask(Test3, null);
                ThreadWRR.Start();
                
                while (ThreadWRR.IsRunning)
                {
                    //Console.WriteLine("C:去加油");
                }
                Console.WriteLine("C:全部完毕,开始装车咯");
                Console.ReadKey();
            }
    
            static void Test1(object s)
            {
                Console.WriteLine(s + "正在组装...");
                for (int i = 0; i < 5; i++)
                {
                    Thread.Sleep(500);
                }
                Console.WriteLine(s + "组装完成!");
            }
    
            static void Test2(object s)
            {
                Console.WriteLine(s + "正在打包...");
                for (int i = 0; i < 5; i++)
                {
                  
                    Thread.Sleep(500);
                }
                Console.WriteLine(s + "打包完成!");
            }

      咋一看是A组装一台,B打包一台才是,这里不是只有一台电脑而已嘛?!我认为两个事件已经在不同的线程上,需要相关业务逻辑去控制的,应该是我们去控制,不应该影响线程内部,才是符合OOA的开闭原则,当然,开发中比这复杂的业务还很多,不一定能应景。欢迎探讨~~

    ThreadWRR类库代码:

     public sealed class ThreadWRR
        {
            private readonly static object objLock = new object();
    
            private static bool isRunning = false;
            private static RunningType runningType = RunningType.Order;
            private static List<Thread> lsThread = null;
            private static List<MethodParameter> listTask = null;
            /// <summary>
            /// 线程是否正在运行
            /// </summary>
            public static bool IsRunning
            {
                get
                {
                    Thread.Sleep(1000);
                    if (runningType == RunningType.Order)
                    {
                        return isRunning;
                    }
                    else
                    {
                        if (lsThread != null && lsThread.Count > 0)
                        {
                            int iFinish = 0;
                            lsThread.ForEach((th) =>
                            {
                                if (th.ThreadState == ThreadState.Stopped)
                                {
                                    iFinish++;
                                }
                            });
                            return iFinish != lsThread.Count;
                        }
                        return false;
                    }
                }
            }
    
            /// <summary>
            /// 等待所有线程
            /// </summary>
            public static void WaitAllTask()
            {
                while (IsRunning)
                {
                }
            }
    
            /// <summary>
            /// 初始化线程
            /// </summary>
            /// <param name="runType">运行方式</param>
            public static void Init(RunningType runType)
            {
                listTask = new List<MethodParameter>();
                lsThread = new List<Thread>();
                isRunning = false;
                runningType = runType;
            }
    
            /// <summary>
            ///  添加运行方法
            /// </summary>
            /// <param name="title"></param>
            /// <param name="method">方法名</param>
            /// <param name="parameter">方法参数</param>
            public static void AddTask(string title, FuncDelegateWithPara method, object parameter)
            {
                listTask.Add(new MethodParameter(title, method, parameter));
            }
           
            /// <summary>
            /// 添加运行方法
            /// </summary>
            /// <param name="title"></param>
            /// <param name="method">方法名</param>
            public static void AddTask(string title, FuncDelegate method)
            {
                listTask.Add(new MethodParameter(title, method));
            }
    
            /// <summary>
            /// 开始运行
            /// </summary>
            public static void Start()
            {
                if (!isRunning)
                {
                    lock (objLock)
                    {
                        if (!isRunning)
                        {
                            isRunning = true;
                            new Thread(() =>
                            {
                                switch (runningType)
                                {
                                    case RunningType.Order:
                                        OrderTask();
                                        break;
                                    case RunningType.Concurrent:
                                        ConcurrentTask();
                                        break;
                                }
                            }) { IsBackground = true }.Start();
                        }
                    }
                }
            }
    
            private static void OrderTask()
            {
                foreach (MethodParameter funcObj in listTask)
                {
                    IAsyncResult ia = null;
                    if (funcObj.FuncWithPara == null)
                    {
                        ia = BeginInvoke(funcObj.Func);
                    }
                    else
                    {
                        ia = BeginInvoke(funcObj.FuncWithPara,funcObj.Parameter);
                    }
                    while (!ia.IsCompleted)
                    {
                        Thread.Sleep(500);
                    }
                }
                isRunning = false;
            }
    
            private static void ConcurrentTask()
            {
                foreach (MethodParameter funcObj in listTask)
                {
                    Thread thread = null;
                    if (funcObj.FuncWithPara == null)
                    {
                        thread = new Thread(new ThreadStart(funcObj.Func)) { IsBackground = true };
                        thread.Start();
                    }
                    else
                    {
                        thread = new Thread(new ParameterizedThreadStart(funcObj.FuncWithPara)) { IsBackground = true };
                        thread.Start(funcObj.Parameter);
                    }
                    lsThread.Add(thread);
                }
            }
    
    
            #region BeginInvoke / Invoke
    
            public static void Invoke(FuncDelegate func)
            {
                func.Invoke();
            }
    
            public static void Invoke(FuncDelegateWithPara func, object para)
            {
                func.Invoke(para);
            }
    
            public static IAsyncResult BeginInvoke(FuncDelegate func)
            {
                return func.BeginInvoke(null, null);
            }
    
            public static IAsyncResult BeginInvoke(FuncDelegateWithPara func, object para)
            {
                return func.BeginInvoke(para, null, null);
            }
    
            public static void Invoke(System.Windows.Forms.Control owner, FuncDelegate func)
            {
                if (owner.InvokeRequired)
                {
                    owner.Invoke(func);
                }
                else
                {
                    func();
                }
            }
    
            public static void Invoke(System.Windows.Forms.Control owner, FuncDelegateWithPara func, object para)
            {
                if (owner.InvokeRequired)
                {
                    owner.Invoke(func, para);
                }
                else
                {
                    func(para);
                }
            } 
            #endregion
    
            private class MethodParameter
            {
                public FuncDelegate Func = null;
                public FuncDelegateWithPara FuncWithPara = null;
                public object Parameter = null;
                public string title = "";
    
                public MethodParameter(string title, FuncDelegate func)
                {
                    this.title = title;
                    this.Func = func;
                }
                public MethodParameter(string title, FuncDelegateWithPara func, object para)
                {
                    this.title = title;
                    this.FuncWithPara = func;
                    this.Parameter = para;
                }
            }
        }
    
        public delegate void FuncDelegateWithPara(object parameter);
        public delegate void FuncDelegate();
    
    
        /// <summary>
        /// 运行方式
        /// </summary>
        public enum RunningType
        {
            /// <summary>
            /// 顺序运行
            /// </summary>
            Order = 0x01,
    
            /// <summary>
            /// 并发运行
            /// </summary>
            Concurrent = 0x02
        }
    View Code
  • 相关阅读:
    pgfplots画二维图真的很方便,多例比较
    LaTeX技巧206:使用gather输入多行公式的技巧
    LaTeX技巧205:使用split输入多行公式技巧
    LaTeX技巧207:使用align环境输入多行公式的技巧
    LaTeX技巧24:LaTeX常用命令集锦
    CTEX
    Latex常用指令学习
    LATEX数学公式基本语法
    LaTeX使用技巧
    C 命令行参数
  • 原文地址:https://www.cnblogs.com/EminemJK/p/6110422.html
Copyright © 2011-2022 走看看