我们经常会遇到生产者消费者模式,比如前端各种UI操作事件触发后台逻辑等。在这种典型的应用场景中,我们可能会有4个业务处理逻辑(下文以P代表生产者,C代表消费者):
1. FIFO(先进先出)
P产生1,2,3,4,5,6,3,2
C处理顺序应为1,2,3,4,5,6,3,2
2.LIFO(后进先出)
P产生1,2,3,4,5,6,3,2
C处理顺序应为2,3,6,5,4,3,2,1
3.Dynamic FIFO(我定义为:去掉相同数据的FIFO, 如果产生的数据队列里已经有相同数据,后进的数据优先级高)
P产生1,2,3,4,5,6,3,2
C处理顺序为1,4,5,6,3,2
4.Dynamic LIFO(我定义为:去掉相同数据的LIFO, 如果产生的数据栈里已经有相同数据,后进的数据优先级高)
P产生1,2,3,4,5,6,3,2
C处理顺序为2,3,6,5,4,1
1,2情况为基本处理逻辑,3,4可能和我们实际场景有关系(包括:判断相同的逻辑可能不同、已存在和后续数据哪个优先级高)
定义上述4种场景的通用接口以及其遍历类
public interface IScheduler : IEnumerable<Task >
{
void Add (Task t);
void Remove (Task t);
int Count { get; }
Task this [int index] { get; set ; }
}
public class SchedulerEnumerator : IEnumerator< Task>
{
private IScheduler _collection;
private int _currentIndex;
private Task _currentTask;
public SchedulerEnumerator (IScheduler collection)
{
_collection = collection ;
_currentIndex = -1;
_currentTask = default (Task);
}
public bool MoveNext()
{
//Avoids going beyond the end of the collection.
if (++_currentIndex >= _collection. Count)
{
return false ;
}
else
{
// Set current box to next item in collection.
_currentTask = _collection [_currentIndex];
}
return true ;
}
public void Reset() { _currentIndex = -1; }
void IDisposable .Dispose() { }
public Task Current
{
get { return _currentTask; }
}
object IEnumerator .Current
{
get { return Current; }
}
}
实现我们自己的任务调度类模板,可以通过T传递我们想要的队列类型
public class TaskSchedulerBase <T> : TaskScheduler
where T : IScheduler , new ()
{
private Thread _processThread;
private readonly object _lock = new object ();
public TaskSchedulerBase()
{
_processThread = new Thread (this.Process);
}
private void Process()
{
lock (_lock)
{
var tasks = GetScheduledTasks();
if (null != tasks)
{
foreach (var t in tasks)
{
TryExecuteTask(t);
TryDequeue(t);
}
}
}
}
protected override void QueueTask( Task task)
{
lock (_lock)
{
Scheduler.Add(task);
if (_processThread.ThreadState.Equals(ThreadState .Stopped))
{
_processThread = new Thread (Process);
}
if (!_processThread.IsAlive
&& !_processThread.ThreadState.Equals( ThreadState.Running))
{
try
{
_processThread.Start();
}
catch (System.Exception )
{
if (!_processThread.ThreadState.Equals(ThreadState .Running))
{
_processThread = new Thread (Process);
_processThread.Start();
}
}
}
}
}
protected override bool TryDequeue( Task task)
{
Scheduler.Remove(task);
return true ;
}
protected override IEnumerable< Task> GetScheduledTasks()
{
return Scheduler.ToArray();
}
protected override bool TryExecuteTaskInline( Task task, bool taskWasPreviouslyQueued)
{
if (taskWasPreviouslyQueued)
{
if (TryDequeue(task))
{
return base .TryExecuteTask(task);
}
else
{
return false ;
}
}
else
{
return base .TryExecuteTask(task);
}
}
private readonly T _scheduler = new T();
public T Scheduler
{
get
{
return _scheduler;
}
}
}
实现4种队列
1.FIFO
public class QueueScheduler : IScheduler
{
protected Queue <Task> _queue;
public QueueScheduler ()
{
_queue = new Queue< Task>();
}
public void Add( Task t )
{
if (!Contains (t))
{
_queue.Enqueue (t);
}
}
public void Remove( Task t )
{
_queue.Dequeue ();
}
public bool Contains( Task t )
{
bool found = false;
foreach (var task in _queue )
{
if (t .AsyncState != null && t .AsyncState. Equals(task .AsyncState))
{
found = true ;
break;
}
}
return found ;
}
public bool Contains( Task t , EqualityComparer< Task> comp )
{
throw new NotImplementedException();
}
public IEnumerator <Task> GetEnumerator()
{
return new SchedulerEnumerator( this);
}
IEnumerator IEnumerable .GetEnumerator()
{
return new SchedulerEnumerator( this);
}
public int Count
{
get { return _queue. Count; }
}
public Task this[ int index]
{
get { return (Task) _queue.ToArray ()[index]; }
set { _queue .ToArray()[index] = value; }
}
}
2.LIFO
public class StackScheduler : IScheduler
{
protected Stack <Task> _stack;
public StackScheduler ()
{
_stack = new Stack< Task>();
}
public void Add( Task t )
{
if (!Contains (t))
{
_stack.Push (t);
}
}
public void Remove( Task t )
{
_stack.Pop ();
}
public bool Contains( Task t )
{
bool found = false;
foreach (var task in _stack )
{
if (t .AsyncState != null && t .AsyncState. Equals(task .AsyncState))
{
found = true ;
break;
}
}
return found ;
}
public bool Contains( Task t , EqualityComparer< Task> comp )
{
throw new NotImplementedException();
}
public IEnumerator <Task> GetEnumerator()
{
return new SchedulerEnumerator( this);
}
IEnumerator IEnumerable .GetEnumerator()
{
return new SchedulerEnumerator( this);
}
public int Count
{
get { return _stack. Count; }
}
public Task this[ int index]
{
get { return (Task) _stack.ToArray ()[index]; }
set { _stack .ToArray()[index] = value; }
}
}
3.Dynamic FIFO
public class DynamicQueueScheduler : IScheduler
{
protected List <Task> _queue;
public DynamicQueueScheduler ()
{
_queue = new List< Task>();
}
public virtual void Add(Task t)
{
Task oldTask = null;
if (Contains (t, out oldTask ))
{
_queue.Remove (oldTask);
}
_queue.Add (t);
}
public virtual void Remove(Task t)
{
_queue.Remove (t);
}
public virtual bool Contains(Task t)
{
Task oldTask = null;
bool found = Contains( t, out oldTask);
return found ;
}
public virtual bool Contains(Task t, out Task oldTask)
{
bool found = false;
oldTask = null ;
foreach (var task in _queue )
{
if (t .AsyncState != null && t .AsyncState. Equals(task .AsyncState))
{
oldTask = task ;
found = true ;
break;
}
}
return found ;
}
public virtual bool Contains(Task t, EqualityComparer<Task > comp)
{
throw new NotImplementedException();
}
public IEnumerator <Task> GetEnumerator()
{
return new SchedulerEnumerator( this);
}
IEnumerator IEnumerable .GetEnumerator()
{
return new SchedulerEnumerator( this);
}
public int Count
{
get { return _queue. Count; }
}
public Task this[ int index]
{
get { return (Task) _queue[index]; }
set { _queue [index] = value; }
}
}
4.Dynamic LIFO
public class DynamicStackScheduler : IScheduler
{
protected List <Task> _queue;
public DynamicStackScheduler ()
{
_queue = new List< Task>();
}
public void Add( Task t )
{
Task oldTask = null;
if (Contains (t, out oldTask ))
{
_queue.Remove (oldTask);
}
_queue.Insert (0,t);
}
public void Remove( Task t )
{
_queue.Remove (t);
}
public bool Contains( Task t )
{
Task oldTask = null;
bool found = Contains( t, out oldTask);
return found ;
}
public bool Contains( Task t , out Task oldTask )
{
bool found = false;
oldTask = null ;
foreach (var task in _queue )
{
if (t .AsyncState != null && t .AsyncState. Equals(task .AsyncState))
{
oldTask = task ;
found = true ;
break;
}
}
return found ;
}
public bool Contains( Task t , EqualityComparer< Task> comp )
{
throw new NotImplementedException();
}
public IEnumerator <Task> GetEnumerator()
{
return new SchedulerEnumerator( this);
}
IEnumerator IEnumerable .GetEnumerator()
{
return new SchedulerEnumerator( this);
}
public int Count
{
get { return _queue. Count; }
}
public Task this[ int index]
{
get { return (Task) _queue[index]; }
set { _queue [index] = value; }
}
}
测试代码
class Program
{
static Queue <int> _queue = new Queue< int>();
//static TaskFactory _factory = new TaskFactory(new TaskSchedulerBase<QueueScheduler>());
//static TaskFactory _factory = new TaskFactory(new TaskSchedulerBase<StackScheduler>());
//static TaskFactory _factory = new TaskFactory(new TaskSchedulerBase<DynamicQueueScheduler>());
//static TaskFactory _factory = new TaskFactory(new TaskSchedulerBase<DynamicStackScheduler>());
static TaskFactory _factory = new TaskFactory (new TaskSchedulerBase<DynamicQueueScheduler >());
static void Main( string[] args )
{
var thread1 = new Thread(Producer );
var thread2 = new Thread(Consumer );
thread1.Start ();
thread2.Start ();
Console.ReadKey ();
}
static void Producer()
{
for (int i = 0; i < 7; i ++)
{
_queue.Enqueue (i);
}
_queue.Enqueue (3);
_queue.Enqueue (2);
}
static void Consumer()
{
while (true )
{
if (_queue .Count > 0)
{
foreach (var i in _queue )
{
_factory.StartNew ((s) =>
{
Console.Write ("{0} on thread {1} {2}\n", s, Thread.CurrentThread .ManagedThreadId,
DateTime.Now .ToLongTimeString());
}, i);
}
_queue.Clear ();
}
else
{
Thread.Sleep (1);
}
}
}
}
- #queue队列 #生产者消费者模型
#queue队列 #生产者消费者模型 #queue队列 #有顺序的容器 #程序解耦 #提高运行效率 #class queue.Queue(maxsize=0) #先入先出 #class queue.L ...
- 第三节: List类型的介绍、生产者消费者模式、发布订阅模式
一. List类型基础 1.介绍 它是一个双向链表,支持左进.左出.右进.右出,所以它即可以充当队列使用,也可以充当栈使用. (1). 队列:先进先出, 可以利用List左进右出,或者右进左出(Lis ...
- python2.0_s12_day9之day8遗留知识(queue队列&生产者消费者模型)
4.线程 1.语法 2.join 3.线程锁之Lock\Rlock\信号量 4.将线程变为守护进程 5.Event事件 * 6.queue队列 * 7.生产者消费者模型 4.6 queue队列 que ...
- 利用J.U.C中的lock和condition实现生产者消费者模式
package lockTest; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.conc ...
- Java多线程15:Queue、BlockingQueue以及利用BlockingQueue实现生产者/消费者模型
Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移 ...
- Python学习笔记——进阶篇【第九周】———线程、进程、协程篇(队列Queue和生产者消费者模型)
Python之路,进程.线程.协程篇 本节内容 进程.与线程区别 cpu运行原理 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Ev ...
- 【Python@Thread】queue模块-生产者消费者问题
python通过queue模块来提供线程间的通信机制,从而可以让线程分项数据. 个人感觉queue就是管程的概念 一个生产者消费者问题 from random import randint from ...
- python多线程编程-queue模块和生产者-消费者问题
摘录python核心编程 本例中演示生产者-消费者模型:商品或服务的生产者生产商品,然后将其放到类似队列的数据结构中.生产商品中的时间是不确定的,同样消费者消费商品的时间也是不确定的. 使用queue ...
- stl容器学习——queue,stack,list与string
目录 头文件 string 目录部分 1.string的定义及初始化 ① 用一个字符串给另一个字符串赋值 ②用字符串常量对字符串进行赋值 ③ 用n个相同的字符对字符串赋值 2.string的运算符及比 ...
随机推荐
- Hadoop相关知识整理系列之一:HBase基本架构及原理
1. HBase框架简单介绍 HBase是一个分布式的.面向列的开源数据库,它不同于一般的关系数据库,是一个适合于非结构化数据存储的数据库.另一个不同的是HBase基于列的而不是基于行的模式.HBas ...
- iOS下的WiFi开发
iOS下Wi-Fi开发需要添加依赖库SystemConfiguration.framework,在需要使用Wi-Fi信息的控制器下引入头文件#import <SystemConfiguratio ...
- 高通LCD驱动调试
本文转载自:http://www.itgo.me/a/x6305658852004979994/lcd%20qcom 来自 :http://blog.csdn.net/dacaozuo/article ...
- struts2数据类型转换详解
Web应用程序的交互都是建立在HTTP之上的,互相传递的都是字符串.也就是说服务器接收到的来自用户的数据只能是字符串或者是字符数组,而在Web应用的对象中,往往使用了多种不同的类型,如整数(int). ...
- Fatal error: cannot create 'R_TempDir'
[user@mgmt dir]$ R Fatal error: cannot create 'R_TempDir' [user@mgmt dir]$ ll -ad /tmp drwxrwxrwt. 2 ...
- HTML图片热区 map area 标签
实例 <img src ="planets.gif" alt="Planets" usemap ="#planetmap" /> ...
- 【P2016】战略游戏(贪心||树状DP)
这个题真是...看了一会之后,发现有一丝丝的熟悉,再仔细看了看,R,这不是那个将军令么...然后果断调出来那个题,还真是,而且貌似还是简化版的...于是就直接改了改建树和输入输出直接交了..阿勒,就2 ...
- Hive数据类型总结
转载自:http://blog.csdn.net/chenxingzhen001/article/details/20901045 Hive的内置数据类型可以分为两大类:(1).基础数据类型:(2). ...
- 整体二分learning
整体二分是一个离线的做法 目前可以解决求区间第k大问题 当然划分树主席树都可以的样子.. 为什么我老学一些解决同种问题的算法.. 主要思想大概是这样的: 如果要求[l,r]的区间第K大 而这个区间内 ...
- Qt QSortFilterProxyModel示例代码, 使用方法
1. QSortFilterProxyModel不能单独使用,它只是一个"代理",真正的数据需要另外的一个model提供,而且它是用来排序和过滤的. 2. 实现代码 #ifndef ...