改进版的线程池(仿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
- 改进版的线程池(仿java的ScheduledFuture)
- 一个简单的线程池(仿java的ScheduledFuture)
- 线程池用法的改进
- Java线程(四):Delayed、ScheduledFuture、RunnableScheduledFuture
- Android_高仿ios左滑删除的(改进版)
- ScheduledFuture
- 多线程(六):线程的多次汇合控制改进版
- 线程的改进--------AsyncTask 介绍
- C#仿JAVA CountDownLatch的线程同步工具
- 我原来的单线程扫描器的改进版(多线程)
- 普通接收函数的改进(时间片->线程实现)
- python编程(改进的线程同步方式)
- 我原来的单线程扫描器的改进版(多线程)
- Java抓图程序的实现(改进版)
- 分享一个改进版的仿MSN/QQ弹出窗口(C#)
- 仿360在Launcher画面显示内存使用率的浮窗(改进版)
- “超长数字减法(不考虑符号,仿人计算) ”的改进
- 对《C#高仿腾讯QQ截图程序》的改进
- Installing OpenCV 2.1 in Ubuntu
- HDU2011~2015——题目合集
- 一款在京东众筹上引爆潮流的神灯--fan花音乐神灯
- HDU1412-{A} + {B},通过率并不高,但同样是用一个很简洁的函数unique,超短代码水过~
- 获取文件资源Properties
- 改进版的线程池(仿java的ScheduledFuture)
- android studio 多渠道打包
- LNMP环境下开启php的扩展
- File类的常用方法
- 国内使用谷歌健身的方法
- 面对多个offer 该如何做出正确的选择
- 程序员到底是一个什么职业?
- plotting pieces
- 一款实用的火车票订票APP--高铁管家