111,128
社区成员
发帖
与我相关
我的任务
分享 BlockingColletion<int> _blockQueue=new BlockingColletion<int>(bounderCapactiy:1);//因为你每次只要1个值,所以我限流1,如果这个值没有用掉,该类自己会保持lock不用你管理
而接收线程里则会用可取消滴Task去订阅这个队列(目前的语法环境,本身建议弃用Theah线程,而使用Task代替)
Task t=new Task(()=>{
while(!cancelToken.IsCancellationRequested) //如果没收到取消指令
{
foreach(var item in __blockQueue.getConsumingEnumerable()) //取出队列里的缓存的值
{
//这个item就是上次你压入队列的值,因为上面限流了,实际上你也指取得到上次的,不过你这次你已经取了,所以生产者可以继续加
}
}
});
t.start()using System;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
private static object flag = new object();
private static long x;
private static string y;
static void Main(string[] args)
{
var h = new Thread(t);
h.Start();
Thread.Sleep(1000);
h.Abort();
Console.WriteLine("x={0}, y={1}", x, y);
Console.WriteLine();
Console.ReadLine();
}
static void t()
{
try
{
lock (flag)
{
x = DateTime.Now.Ticks;
y = x.ToString();
Thread.Sleep(10000);
}
}
catch
{
Console.WriteLine("catch操作");
}
}
}
}
这里显然在读取x、y的时候不需要lock。而且实际上在方法 t 中也其实根本不需要写 lock。因为根本不存在数值得一致性冲突问题,用什么 lock 呢?
而你为什么画蛇添足地总是纠结lock?我猜你是纠结所谓的“资源”这个又响亮有没有意义的词儿。
假设代码写成using System;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
private static object flag = new object();
private static long x;
private static string y;
static void Main(string[] args)
{
var h = new Thread(t);
h.Start();
Thread.Sleep(1000);
lock (flag)
{
Console.WriteLine("x={0}, y={1}", x, y);
}
Console.WriteLine();
Console.ReadLine();
}
static void t()
{
try
{
lock (flag)
{
x = DateTime.Now.Ticks;
y = x.ToString();
Thread.Sleep(10000);
}
}
catch
{
Console.WriteLine("catch操作");
}
}
}
}
这里主线程会被阻塞10秒钟之后才能打印输出结果。这个时候是锁了什么x、y资源了么?
lock 就是根据 flag 变量而做的互斥操作,跟 lock 语句块中的什么“资源”没有半点关系。当 lock 语句块结束,或者因为异常而结束了语句块的时候,lock 锁依赖的阻塞就会结束,就允许另一个等待 Monitor 通知的线程进入。整个lock过程只跟 flag 有关,不用纠结多余的什么“资源”,这个机制也不可能那么低效率地去处理什么资源。