改进版的线程池(仿java的ScheduledFuture)

来源:互联网 发布:linux snmp软件下载 编辑:程序博客网 时间:2024/06/05 20:14

需求

上一篇写了一个线程池http://blog.csdn.net/ylbs110/article/details/51172428
经过仔细查询javaAPI才发现我前面一个方案并不符合要求:java中的newSingleThreadScheduledExecutor是个单线程池,也就是说一直只有一个线程在跑,新添加的任务会存储起来,线程每次跑完一个任务再获取一个新任务继续跑,没有任务则等待任务。

实现

Executors实例化的其他类型线程池基本都是和池中的线程数量有关,实现方式并不相同,所以完全可以写一个通用的线程池,输入线程数量生成不同的线程池,默认线程数为1即可。
既然不用在unity中使用,线程当然可以用Task实现,并用CancellationToken来实现线程的关闭。
ScheduledFuture中并不需要有线程,仅仅存储任务的委托以及任务的调用方式:是否延迟启动,是否循环运行,是否已经开始,是否已经完成,是否取消等。
任务的调度完全可以用队列来实现:新添加的任务放在队列前面,使用的时候从队列后面拿出一个任务。这样就可以满足先申请的任务先运行了。
个人觉得上个方案写得太烂了,相比而言这个方案简单易懂还好用。
代码比较简单,不注释太多。

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Timers;using System.Threading;using System.Threading.Tasks;namespace TvMenuLibrary{    public class Runnable { //java中没有委托,这个类相当于一个万能委托事件的类        public Runnable(Action handle)        {            thisEvent += handle;        }        event Action thisEvent;        public void run()        {            if (thisEvent != null)                     thisEvent();                        }        public Action getEvent()        {            return thisEvent;        }    }    public class ScheduledFuture//线程    {        TimeSpan waitTime;        TimeSpan cycleTime;        bool isCycle;        bool isRunning = false;        bool iscancel = false;        bool isDone = false;        event Action thisEvent;        public void run()        {            if (isDone)                return;            Thread.Sleep(waitTime);            if (thisEvent != null)            {                isRunning = true;                if (isCycle)                    while (!iscancel)                    {                        Thread.Sleep(cycleTime);                        thisEvent();                    }                else if (!isCycle)                    thisEvent();            }            isDone = true;        }        public ScheduledFuture(Runnable runnable, int waitTime, int cycleTime, long timeSpan)        {                      thisEvent = runnable.getEvent();            this.waitTime = new TimeSpan(waitTime * timeSpan);            if (cycleTime >= 0)            {                this.cycleTime = new TimeSpan(cycleTime * timeSpan);                this.isCycle = true;            }            else                this.isCycle = false;                 }        public bool cancel()        {            if (isDone)                return false;            else if (iscancel)                return false;            else if (isRunning && !iscancel)                return false;            else {                isDone = true;                return iscancel = true;            }        }        public bool isCancel {            get { return iscancel; }        }    }    public class ScheduledExecutorService//线程池    {        public Queue<ScheduledFuture> futureList;        bool shutdown=false;        CancellationTokenSource source;        CancellationToken token;        public ScheduledExecutorService(int i=1)        {            source = new CancellationTokenSource();            token = source.Token;            futureList = new Queue<ScheduledFuture>();            run(i);        }        async void run(int i){            while (i-->0)                await Task.Run(() =>                {                    while (!token.IsCancellationRequested)                        if (futureList != null && futureList.Count > 0)                            futureList.Dequeue().run();                }, token);        }        public ScheduledFuture schedule(Runnable runnable, int time, long timeSpan)        {            if (shutdown)                return null;            return scheduleAtFixedRate(runnable, time, -1, timeSpan);        }        public ScheduledFuture scheduleAtFixedRate(Runnable runnable, int waitTime, int cycleTime, long timeSpan)        {            if (shutdown)                return null;            ScheduledFuture future = new ScheduledFuture(runnable, waitTime, cycleTime, timeSpan);            futureList.Enqueue(future);            return future;        }        public void shutdownNow()//关闭所有正在使用的线程        {                        source.Cancel();            shutdown = true;            int i = futureList.Count;            while (i-- > 0)                futureList.Dequeue().cancel();        }        public bool isShutdown()        {            return shutdown;        }    }    public static class Executors {//“翻译”的java中的构造类,也可以不通过它创建线程池        public static ScheduledExecutorService newSingleThreadScheduledExecutor() {            return new ScheduledExecutorService();        }        public static ScheduledExecutorService newThreadScheduledExecutor(int i)        {            return new ScheduledExecutorService(i);        }}

测试

测试类

    class Test {        public void funcA() {            Console.WriteLine("A");        }        public void funcB()        {            Console.WriteLine("B");        }        public void funcC()        {            Console.WriteLine("C");        }    }

调用

ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();Console.WriteLine("队列中的任务数量:" + service.futureList.Count);ScheduledFuture runA = service.schedule(new Runnable(test.funcA), 1, TimeSpan.TicksPerSecond);ScheduledFuture runB = service.schedule(new Runnable(test.funcB), 1, TimeSpan.TicksPerSecond);ScheduledFuture runC = service.schedule(new Runnable(test.funcC), 1, TimeSpan.TicksPerSecond);Console.WriteLine("队列中的任务数量:" + service.futureList.Count);ScheduledFuture runD = service.schedule(new Runnable(test.funcC), 1, TimeSpan.TicksPerSecond);ScheduledFuture runE = service.schedule(new Runnable(test.funcC), 1, TimeSpan.TicksPerSecond);ScheduledFuture runF = service.schedule(new Runnable(test.funcC), 1, TimeSpan.TicksPerSecond);Thread.Sleep(5000);Console.WriteLine("队列中的任务数量:" + service.futureList.Count);service.shutdownNow();Console.WriteLine("队列中的任务数量:" + service.futureList.Count);Console.WriteLine(service.isShutdown());

运行结果

队列中的任务数量:0队列中的任务数量:3ABCC队列中的任务数量:1队列中的任务数量:0TrueC

转载请注明出处:http://blog.csdn.net/ylbs110/article/details/51224979

1 0
原创粉丝点击