zoukankan      html  css  js  c++  java
  • 多线程实现

    WorkState

        public enum WorkState
        {
            Ready,
            Running,
            Completed
        }

    IWork

        public interface IWork
        {
            WorkState State { get; set; }
            void Perform();
        }

    关键类WorkQueue

    public class WorkQueue
        {
            private List<IWork> _vlstWork = new List<IWork>();

            public void Add(IWork work)
            {
                lock (this)
                {
                    _vlstWork.Add(work);
                }
            }

            public int GetCount(WorkState state)
            {
                lock (this)
                {
                    int count = 0;
                    _vlstWork.ForEach(item =>
                    {
                        if (item.State == state)
                            count++;
                    });
                    return count;
                }
            }

            public IWork GetWork()
            {
                lock(this)
                {
                    foreach (IWork work in _vlstWork)
                        if (work.State == WorkState.Ready)
                            return work;
                    return null;
                }
            }
        }

    重点类ThreadScheduler

    public delegate void AllFinishedHandler();
        public class ThreadScheduler
        {
            private readonly int _viConcurrentLimit = 10;
            private WorkQueue _vWorkQueue = null;

            public AllFinishedHandler OnAllFinished = null;

            public WorkQueue WorkQueue
            {
                get { return _vWorkQueue; }
            }
            public int ConcurrentLimit
            {
                get { return _viConcurrentLimit; }
            }

            public ThreadScheduler():this(new WorkQueue(),10) { }
            public ThreadScheduler(WorkQueue workQueue):this(workQueue,10){ }
            public ThreadScheduler(int concurrent) : this(new WorkQueue(),concurrent) { }
            public ThreadScheduler(WorkQueue workQueue,int concurrent)
            {
                _vWorkQueue = workQueue;
                _viConcurrentLimit = concurrent;
            }

            public void StartWork()
            {
                CheckAllFinished();

                while (_vWorkQueue.GetCount(WorkState.Ready) > 0)
                {
                    System.Diagnostics.Trace.WriteLine(_vWorkQueue.GetCount(WorkState.Ready));
                    if (_vWorkQueue.GetCount(WorkState.Running) < _viConcurrentLimit)
                    {
                        IWork work = _vWorkQueue.GetWork();
                        work.State = WorkState.Running;
                        if (work != null)
                        {
                            System.Threading.Thread thread = new System.Threading.Thread(() => {
                                work.Perform();
                                work.State = WorkState.Completed;
                            });
                            thread.IsBackground = true;
                            thread.Start();
                        }
                    }
                }
            }

        //这里要是用 一个volatile变量 来实现更准确的测试完成时间。不需要新起来一个线程啊!当然这个方法的调用位置需要修改。

            private void CheckAllFinished()
            {
                System.Threading.Thread thread = new System.Threading.Thread(() => {
                    while (_vWorkQueue.GetCount(WorkState.Running) + _vWorkQueue.GetCount(WorkState.Ready) > 0)
                    {
                        System.Threading.Thread.Sleep(50);
                    }
                    if (OnAllFinished != null)
                        OnAllFinished();
                });
                thread.IsBackground = true;
                thread.Start();
            }

        }

     测试类TestWork

    public class TestWork : IWork
        {
            private string _vsName = string.Empty;
            private static int _viIndex = 1;
            private WorkState _vState = WorkState.Ready;

            public WorkState State
            {
                get { return _vState; }
                set { _vState = value; }
            }

            public TestWork() { }
            public TestWork(string name)
            {
                _vsName = name;
            }

            public void Perform()
            {
                Console.WriteLine("{0}.{1}--------Thread:{2}",_viIndex++,_vsName,System.Threading.Thread.CurrentThread.Name);
            }
        }

    看看 效果:

    class Program
        {
            static void Main(string[] args)
            {
                List<string> list = new List<string>();// new List<string>(new string[] { "Sunday", "Monday", "Tuesday", "Wednesday" });

                #region Test One
                /*
                int count = 2;
                System.Threading.Thread[] threadArray = new System.Threading.Thread[count];
                for (int i = 0; i < count; i++)
                {
                    threadArray[i] = new System.Threading.Thread(new TestWork(list[i]).Perform);
                    threadArray[i].Name = string.Format("WT#{0}", i);
                    threadArray[i].IsBackground = true;
                }

                foreach (System.Threading.Thread thread in threadArray)
                {
                    thread.Start();
                }
                */
                #endregion

                Random random=new Random();
                for (int i = 0; i < 10000; i++)
                {
                    list.Add(random.Next(10000).ToString());
                }

                DateTime startDateTime = DateTime.Now;
                Console.WriteLine("There are {0} works as follows:", list.Count);
                ThreadScheduler vThreadScheduler = new ThreadScheduler(8000);
                list.ForEach(item=>{
                    vThreadScheduler.WorkQueue.Add(new TestWork(item));
                });
                vThreadScheduler.OnAllFinished += () =>
                {
                    DateTime endDateTime=DateTime.Now;
                    Console.WriteLine("Works:{3},Used Time={0} <--- {1}-{2}",
                            endDateTime-startDateTime,endDateTime.ToString(),
                            startDateTime.ToString(),
                            vThreadScheduler.ConcurrentLimit
                        );
                };
                vThreadScheduler.StartWork();

                Console.WriteLine("Over");
                Console.Read();
            }
        }

    测试发现当thread数量为任务数量一半的时候比80%要 快,比100%更快。当然这里的任务是小任务。

     源码下载

  • 相关阅读:
    POJ 2135 Farm Tour(最小费用最大流,变形)
    HDU 1503 Advanced Fruits (LCS,变形)
    HDU Senior's Gun (水题)
    POJ 3648 Wedding (2-SAT,经典)
    HDU 3549 Flow Problem 流问题(最大流,入门)
    解决在eclipse中导入项目名称已存在的有关问题
    如何将js导入时的小红叉去掉
    servlet传值到servlet传值问题
    转发重定向的用法
    parameter与attribute的使用场合(转载自草原和大树)
  • 原文地址:https://www.cnblogs.com/hongjiumu/p/3416214.html
Copyright © 2011-2022 走看看