多线程 Join 方法之疑问。

z191288065 2017-03-29 09:05:54
t.Join()方法是等待线程t结束,在执行主线程,那么我就有个疑问了,Join不是阻塞线程吗,等待另一个线程执行完成,那么结果应该始终是0,为什么下面这个简单的加减计算器例子,结果不一定是0,Why?Why?Why?Why?Why?

static void Main(string[] args)
{
Console.WriteLine("Incorrect counter");

var c = new Counter();

var t1 = new Thread(() => TestCounter(c));
var t2 = new Thread(() => TestCounter(c));
var t3 = new Thread(() => TestCounter(c));
t1.Start();
t1.Join();
t2.Start();
t2.Join();
t3.Start();
t3.Join();

Console.WriteLine("Total count: {0}", c.Count);
Console.WriteLine("--------------------------");

Console.WriteLine("Correct counter");
}

static void TestCounter(CounterBase c)
{
for (int i = 0; i < 100000; i++)
{
c.Increment();
c.Decrement();
}
}

class Counter : CounterBase
{
public int Count { get; private set; }

public override void Increment()
{
Count++;
}

public override void Decrement()
{
Count--;
}
}
abstract class CounterBase
{
public abstract void Increment();

public abstract void Decrement();
}

...全文
185 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
这就是数据库原理中事务级别里所谓的更改丢失,多次更新从结果上看只纪录到了一次
token不能为空 2017-03-29
  • 打赏
  • 举报
回复
t1.Start(); t1.Join(); t2.Start(); t2.Join(); t3.Start(); t3.Join(); 相当于单线程吧 后面那种写法才是三个线程同时开工
xuzuning 2017-03-29
  • 打赏
  • 举报
回复
t1.Start(); t1.Join(); t2.Start(); t2.Join(); t3.Start(); t3.Join(); 你这样写是不可能出现 非0 的 但这样写 t1.Start(); t2.Start(); t3.Start(); t1.Join(); t2.Join(); t3.Join(); 就可能出现 非0
stherix 2017-03-29
  • 打赏
  • 举报
回复
在c#里面 count++; count--; 这样的操作就不是线程安全的,因为它们不是原子操作 count++实际等价于count=count+1 取count值到堆栈,对其加1,将其值写回count 比如count为1 可能2个线程同时取其值,都是1,然后+1之后都是等于2,写回去也是2 按照正常流程,count是被累加了2次 应该等于3的
Forty2 2017-03-29
  • 打赏
  • 举报
回复
Count++; 不是线程安全的。 虽然它是最简单不过的一个语句,在CPU级别上,却需要多个操作。 具体的分析可以参考下贴2楼。 http://bbs.csdn.net/topics/260016855
z191288065 2017-03-29
  • 打赏
  • 举报
回复

书上解释这样,我怎么感觉和我平时的认知不同也,我去
z191288065 2017-03-29
  • 打赏
  • 举报
回复
这种调整有什么影响,如果按照该书的写法就有可能不是0
z191288065 2017-03-29
  • 打赏
  • 举报
回复



朋友们,我错了,我把树上的例子代码稍稍调整了下,原书代码例子是这样的:

t1.Start();
t2.Start();
t3.Start();
t1.Join();
t2.Join();
t3.Join()

token不能为空 2017-03-29
  • 打赏
  • 举报
回复
循环100次都是0
xdashewan 2017-03-29
  • 打赏
  • 举报
回复
我测了几千次也没出过不是0的
z191288065 2017-03-29
  • 打赏
  • 举报
回复
该例子来自于c#多线程编程实战 ,Chapter1-10.1 在c#中试用Lock关键字

111,125

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧