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

需求

上一篇写了一个线程池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
队列中的任务数量:3
A
B
C
C
队列中的任务数量:1
队列中的任务数量:0
True
C

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

你可能感兴趣的:(java,线程,线程池,C#,task)