需求
上一篇写了一个线程池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