一个简单的线程池(仿java的ScheduledFuture)

需求

最近公司有一个奇葩的需求:让我把一个java的客户端插件转换为C#版本。
转换并不难,由于有java客户端的源码,基本只要照着“翻译”即可实现,实际上我是将java代码复制到C#工程中然后通过改bug的方式实现的。
由于java和C#很相似,这个干问题并不大,但是有几个java的库C#并没有。而且由于我想要将C#的DLL放到Unity中使用,所以没办法使用高版本的.NET库,导致我需要手动实现这几个库,其中就包括java的线程池ScheduledExecutorService及其线程ScheduledFuture。
虽然最终由于Unity对多线程支持并不好导致DLL无法在Unity中正常运行而不得不使用WPF来做客户端(这样就可以使用更高级的.NET库了),但是自己实现库的过程也是对自己的锻炼。

实现

关于线程参考:http://www.cnblogs.com/miniwiki/archive/2010/06/18/1760540.html
由于每次申请线程系统都会有一个反应时间,所以需要提前申请一定数量的备用线程放在线程池中,当对线程池提交申请线程的需求时,直接从备用线程池中调出一个线程来使用,使用完后再将线程转移到备用线程池。为了让备用线程池一直有足够的线程可用并且不会因为提前申请过多线程导致浪费,所以单独有一个线程对备用线程池进行动态管理:太少了就分配固定数量,太多了就将数量降低到一定数目。
直接上代码,代码简单就不注释太多了

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using System.Threading;

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 : IDisposable//线程
    {
        Thread thread;
        Action<ScheduledFuture> thisPool;

        public TimeSpan waitTime;
        public TimeSpan cycleTime;
        public bool isCycle;

        event Action thisEvent;
        public void run()
        {
            Thread.Sleep(waitTime);
            if (thisEvent != null) {
                if (isCycle)
                    while (true) {
                        Thread.Sleep(cycleTime);
                        thisEvent();
                    }
                else
                    thisEvent();
            }          
        }

        public ScheduledFuture(Action<ScheduledFuture> pool)
        {
            waitTime = new TimeSpan(0);
            cycleTime = new TimeSpan(0);
            isCycle = false;
            thisPool = pool;
            thread = new Thread(run);
            thread.IsBackground = true;
        }
        ~ScheduledFuture() {
            thread.Abort();
        }
        public void reset(Runnable ra, int waitTime, long timeSpan)
        {
            reset(ra, waitTime, -1, timeSpan);
        }
        public void reset(Runnable ra, int waitTime,int cycleTime, long timeSpan)
        {
            thisEvent = ra.getEvent();
            this.waitTime = new TimeSpan(waitTime * timeSpan);
            if (cycleTime >= 0) {
                this.cycleTime = new TimeSpan(cycleTime * timeSpan);
                this.isCycle = true;
            }
            else
                this.isCycle = false;
            thread.Start();
        }
        public bool cancel()
        {
            if (thread.IsAlive) {
                thread.Join();
                thisPool(this);
            }            
            return !thread.IsAlive;
        }
        public bool isCancel {
            get { return !thread.IsAlive; }
        }
        public void Dispose()
        {
            thread.Abort();
        }
    }
    public class ScheduledExecutorService//线程池
    {
        const int futureAutoScale = 3;//自动备用线程数量
        public List<ScheduledFuture> futureList;
        public Queue<ScheduledFuture> handleVoid;
        Thread thread;
        public ScheduledExecutorService()
        {
            futureList = new List<ScheduledFuture>();
            handleVoid = new Queue<ScheduledFuture>();
            autoScaleFuture();
            thread = new Thread(() => { while (true)autoScaleFuture(); });
            thread.IsBackground = true;
            thread.Start();
        }
        ~ScheduledExecutorService()
        {
            foreach (ScheduledFuture fu in futureList)
                fu.Dispose();
            while(handleVoid.Count>0)
                handleVoid.Dequeue().Dispose();
        }
        void autoScaleFuture() {//自动调整备用线程数量
            if (handleVoid.Count < 2)
            {
                int i = futureAutoScale;
                while (i-- > 0)
                {
                    ScheduledFuture future = new ScheduledFuture(addHandleVoid);
                    handleVoid.Enqueue(future);
                }
            }
            while (handleVoid.Count > futureAutoScale+1)
            {
                handleVoid.Dequeue().Dispose();
            }           
        }
        void addHandleVoid(ScheduledFuture future)//将被关闭的线程转移到备用线程中
        {
            if (futureList.Contains(future)) {
                futureList.Remove(future);
                handleVoid.Enqueue(future);
            }            
        }

        public ScheduledFuture schedule(Runnable runnable, int time, long timeSpan)
        {
            return scheduleAtFixedRate(runnable, time, -1, timeSpan);
        }
        public ScheduledFuture scheduleAtFixedRate(Runnable runnable, int waitTime, int cycleTime, long timeSpan)
        {
            while (handleVoid.Count < 1 ) {  }//备用线程库没有足够的线程则等待线程分配
            ScheduledFuture future = handleVoid.Dequeue();
            future.reset(runnable, waitTime, cycleTime, timeSpan);
            futureList.Add(future);
            return future;
        }
        public void shutdownNow()//关闭所有正在使用的线程
        {
            int i = futureList.Count;
            while (i-- > 0) 
                futureList[i].cancel();
        }
        public bool isShutdown()
        {
            if (futureList.Count==0)
                return true;
            return false;
        }
    }
    public static class Executors {//“翻译”的java中的构造类,也可以不通过它创建线程池
        public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
            return new ScheduledExecutorService();
        }
    }
}

测试

测试类

    class Test {

        //public void setReady()
        //{
        // Console.WriteLine("setReady");
        //}
        //public void setNotReady()
        //{
        // Console.WriteLine("setNotReady");
        //}

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

调用

Test test = new Test();
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
Console.WriteLine("使用中的线程数量:" + service.futureList.Count);
Console.WriteLine("线程池闲置线程数量:" + service.handleVoid.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);
Console.WriteLine("线程池闲置线程数量:" + service.handleVoid.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(3500);
Console.WriteLine("使用中的线程数量:" + service.futureList.Count);
Console.WriteLine("线程池闲置线程数量:" + service.handleVoid.Count);
service.shutdownNow();
Console.WriteLine("使用中的线程数量:" + service.futureList.Count);
Console.WriteLine("线程池闲置线程数量:" + service.handleVoid.Count);
Console.WriteLine(service.isShutdown());

运行结果

使用中的线程数量:0
线程池闲置线程数量:3
使用中的线程数量:3
线程池闲置线程数量:3
A
B
C
C
C
C
使用中的线程数量:6
线程池闲置线程数量:3
使用中的线程数量:6
线程池闲置线程数量:3
False
转载请注明出处:http://blog.csdn.net/ylbs110/article/details/51172428

你可能感兴趣的:(java,Runnable,.net,线程池)