博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线程系列07,使用lock语句块或Interlocked类型方法保证自增变量的数据同步
阅读量:6316 次
发布时间:2019-06-22

本文共 1990 字,大约阅读时间需要 6 分钟。

假设多个线程共享一个静态变量,如果让每个线程都执行相同的方法每次让静态变量自增1,这样的做法线程安全吗?能保证自增变量数据同步吗?本篇体验使用lock语句块和Interlocked类型方法保证自增变量的数据同步。

 

□ 线程不安全、数据不同步的做法

 

 
class Program
{
static int sum = 0;
static void Main(string[] args)
{
Stopwatch watch = new Stopwatch();
watch.Start();
Parallel.For(0, Environment.ProcessorCount, i =>
{
for (int j = 0; j < 100000000; ++j)
{
AddOne();
}
});
watch.Stop();
Console.WriteLine("sum={0},用了{1}", sum, watch.Elapsed);
Console.ReadKey();
}
 
static void AddOne()
{
sum++;
}
}
 

○ 变量sum是静态的,供所有线程共享

○ Parallel.For提供并行循环, Environment.ProcessorCount表示处理器的处理,如果有4个CPU,就做4组循环

我们发现,结果不是我们期望的400000000,也就是说,在这种情况下的静态变量自增不是线程安全的,换句话说,无法保证共享数据的同步。

 

□ 通过lock语句块保持数据同步

 

 
 
class Program
{
static int sum = 0;
private static readonly object o = new object();
static void Main(string[] args)
{
Stopwatch watch = new Stopwatch();
watch.Start();
Parallel.For(0, Environment.ProcessorCount, i =>
{
for (int j = 0; j < 100000000; ++j)
{
AddOne();
}
});
watch.Stop();
Console.WriteLine("sum={0},用了{1}", sum, watch.Elapsed);
Console.ReadKey();
}
 
static void AddOne()
{
lock (o)
{
sum++;
}
 
}
}
 
 

这一次,使用lock语句块得到了预期的结果。

 

□ 使用Interlocked保持数据同步

对于int或long类型变量的自增,并且保证类型安全,可以使用Interlocked类。提供的方法包括:

 

○ int Interlocked.Increment(ref int location),自增1

○ long Interlocked.Increment(ref long location),自增1
○ int Interlocked.Decrement(ref int location),自减1
○ long Interlocked.Decrement(ref long location),自减1
○ int Interlocked.Add(ref int location, int value),自增一个值
○ long Interlocked.Add(ref long location, long value),自增一个值

 

 
class Program
{
static int sum = 0;
static void Main(string[] args)
{
Stopwatch watch = new Stopwatch();
watch.Start();
Parallel.For(0, Environment.ProcessorCount, i =>
{
for (int j = 0; j < 100000000; ++j)
{
AddOne();
}
});
watch.Stop();
Console.WriteLine("sum={0},用了{1}", sum, watch.Elapsed);
Console.ReadKey();
}
 
static void AddOne()
{
Interlocked.Increment(ref sum);
}
}
 

使用Interlocked也能保证线程安全、数据同步,但耗时较长。

总结:
○ lock语句块和Interlocked类型方法都能保证自增变量的线程安全、数据同步
○ Interlocked类型方法只适用于int,long类型变量,有一定的局限性

 

线程系列包括:

转载地址:http://xvkaa.baihongyu.com/

你可能感兴趣的文章
[arm驱动]platform第一个程序led灯循环
查看>>
Apache Maven 入门篇 ( 上 )
查看>>
设计模式之行为模式
查看>>
我的友情链接
查看>>
Apache配置文件详解
查看>>
观点:从手机的发展聊聊智能汽车安全
查看>>
alex教学视频--信用卡账单
查看>>
lvs fullnat+ECMP【3】realserver 安装toa模块
查看>>
学习总结
查看>>
我的友情链接
查看>>
总结2015年,展望2016
查看>>
php curl函数获取远程主机的信息
查看>>
被动信息收集之DNS爆破(二)
查看>>
解决虚拟机或物理机ping不通网关故障的方法与思路
查看>>
L7.1 linux shell总结
查看>>
JAVA 对象引用,以及对象赋值
查看>>
CentOS搭建LAMP详细教程
查看>>
Discuz x2.5论坛SEO设置的方法和优化技巧
查看>>
Xcode代码提示失效解决办法
查看>>
技術討論
查看>>