MethodImplOptions.Synchronized的一点讨论
Review代码发现有一个方法加了[MethodImpl(MethodImplOptions.Synchronized)] 属性,这个属性的目的,从名字上就可以看出,是要对所有线程进行同步执行。
对方法加上这个属性之后,会把整个方法体加在一个同步块中,比如下面的代码:
[MethodImpl(MethodImplOptions.Synchronized)]
public static void syncDemo()
{
if (count % != )
{
Thread.Sleep();
count++;
}
}
其实和下面的代码是一样的(SyncMethodCls是包含这个方法的类):
public static void lockDemo()
{
lock (typeof(SyncMethodCls))
{
if (count % != )
{
Thread.Sleep();
count++;
}
}
}
从第二个方法中,可以看到使用[MethodImpl(MethodImplOptions.Synchronized)]这个属性是对整个类型进行加锁的,同步块是整个方法。如果这个类中只有一个静态同步方法还好,如果有两个同步静态方法都使用这个属性进行标注,这两个方法之间就会出现竞态,在一些情况下,你可能并不想让两个不是很相关的方法出现竞态的情况。同一个类型中越多这种静态同步方法,出现的竞争越激励,系统性能也会越差。
上面也说了,使用这个属性之后,是对整个方法进行同步,但是有时候有些条件判断并不需要放在同步块中,比如上面方法中的if 条件,我并不想放到同步块中,因为有时候已经满足条件的线程就不需要再次阻塞了。这种情况在单例中最明显了,首先判断单例的实例是否为空,只有为空的时候,才会去加锁重新生成一个新的实例。
以上方法可以参考单例进行改造,改造后的代码如下:
private static object syncObj = new object();
public static void syncObjDemo()
{
if (count % !=)
{
lock(syncObj)
{
if (count % != )
{
Thread.Sleep();
count++;
}
}
}
}
改造之后,竞争数量明显减少。
下面附上使用[MethodImpl(MethodImplOptions.Synchronized)]竞争情况:

改造之后的竞争情况:

多线程调用情况如下:
for (int i = ; i <= ; i++)
{
ThreadPool.QueueUserWorkItem((t) =>
{
// syncMethodCls.syncDemo();
syncMethodCls.syncObjDemo();
});
}
到此,需要好好说说这个[MethodImpl(MethodImplOptions.Synchronized)]了,MSDN上这样解释:“该方法一次性只能在一个线程上执行。 静态方法在类型上锁定,而实例方法在实例上锁定。 只有一个线程可在任意实例函数中执行,且只有一个线程可在任意类的静态函数中执行。” 总结一句话就是:静态方法锁整个类,实例方法锁整个实例。这句话乍一看挺吓人的,但是如果你的类中只有一个同步方法的话,锁整个类和整个实例影响也不大,但是要确保类和实例在其他地方不会再次被锁,否则会造成死锁的。
所以这个属性,还是尽量不要使用了,不光有可能造成性能问题不说,还有可能造成死锁的严重问题。
说到锁整个类,最近看java多线程的部分,java中有个和C#的lock类似的同步关键字synchronized,好多例子都是直接在方法上加这个关键字,实现方法的同步实现。这个关键字实现的方式应该类似MethodImplOptions.Synchronized,静态方法锁类型,实例方法锁实例,而且如果有条件判断可能还会造成不必要的阻塞。而且由于jdk对synchronized的不断优化,在有些时候并不会马上进行加锁,而是会先自旋一会(以通过浪费CPU时间减少阻塞),可能在某些时候造成CPU时间片的浪费。所以使用的时候,也需要注意。
MethodImplOptions.Synchronized的一点讨论的更多相关文章
- [MethodImpl(MethodImplOptions.Synchronized)]、lock(this)与lock(typeof(...))
对于稍微有点经验的.NET开发人员来说,倘若被问及如何保持线程同步,我想很多人都能说好好几种.在众多的线程同步的可选方式中,加锁无疑是最为常用的.如果仅仅是基于方法级别的线程同步,使用System.R ...
- 警惕32位程序在MethodImplOptions.Synchronized在x64机器上的同步缺陷[z]
https://www.cnblogs.com/junchu25/archive/2012/08/10/2631422.html 上周四产品上线一切运行正常,做了一点小改动后周四晚上发布,周五大量用户 ...
- [MethodImpl(MethodImplOptions.Synchronized)]
在NopCommerce项目的Nop.Core类库中有一个EngineContext类中有一个Initialize方法用到了[MethodImpl(MethodImplOptions.Synchron ...
- C#方法同步 [MethodImpl(MethodImplOptions.Synchronized)]
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- C# Note26: [MethodImpl(MethodImplOptions.Synchronized)]与lock机制
在进行.NET开发时,经常会遇见如何保持线程同步的情况.在众多的线程同步的可选方式中,加锁无疑是最为常用的.如果仅仅是基于方法级别的线程同步,使用System.Runtime.CompilerServ ...
- 对RLC重排序窗口大小的一点讨论
在LTE协议栈的PDCP层和RLC层,都有一个重排序窗口(reordering window),主要用来保证数据的可靠传输,PDCP层的重排序窗口主要用于handover时保证数据的可靠传输,这里暂且 ...
- [MethodImpl(MethodImplOptions.Synchronized)]与lock机制
[MethodImpl(MethodImplOptions.Synchronized)]与lock机制 在进行.NET开发时,经常会遇见如何保持线程同步的情况.在众多的线程同步的可选方式中,加锁无疑是 ...
- 对synchronized的一点理解
一.synchronized的使用(一).synchronized同步方法1. “非线程安全”问题存在于“实例变量”中,如果是方法内部的私有变量,则不存在“非线程安全”问题.2. 如果多个线程共同访问 ...
- 有关动态规划(主要是数位DP)的一点讨论
动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法.20世纪50年代初美国数学家在研究多阶段决策过程的优化问题时, ...
随机推荐
- ssh scp 加端口
scp -P one-infrastructure-api.tar.gz console@172.31.16.2:/root/ ssh -p console@172.31.16.2
- p1 批梯度下降算法
(蓝色字体:批注:绿色背景:需要注意的地方:橙色背景是问题) 一,机器学习分类 二,梯度下降算法:2.1模型 2.2代价函数 2.3 梯度下降算法 一,机器学习分类 无监督学习和监督学习 无监 ...
- Jersey RESTful WebService框架学习(三)使用@QueryParam
介绍:@QueryParamuri路径请求参数写在方法的参数中,获得请求路径附带的参数.比如:@QueryParam("desc") String desc 前端控制 <!D ...
- 【慕课网实战】Spark Streaming实时流处理项目实战笔记三之铭文升级版
铭文一级: Flume概述Flume is a distributed, reliable, and available service for efficiently collecting(收集), ...
- Hadoop-2.8.0分布式安装手册
目录 目录 1 1. 前言 3 2. 特性介绍 3 3. 部署 5 3.1. 机器列表 5 3.2. 主机名 5 3.2.1. 临时修改主机名 6 3.2.2. 永久修改主机名 6 3.3. 免密码登 ...
- Swift: 用Alamofire做http请求,用ObjectMapper解析JSON
跟不上时代的人突然间走在了时代的前列,果然有别样的风景.首先鄙视一下AFNetworking.这个东西实在太难用了.不想封装都不行,要不写一大堆代码. NSURL *URL = [NSURL URLW ...
- 2.虚拟机安装的ubuntu全屏显示
虚拟机下面安装了ubuntu系统,显示的屏幕只有那么一小块儿,不知道如何才能全屏,那么如何全屏呢?且看下面经验. 方法/步骤 打开虚拟机,并点击要更改成全屏的那个ubuntu系统的电源 我的虚拟机名字 ...
- Android-Kotlin简单计算器功能
上一篇博客 Android-Kotlin-配置/入门 配置好了 AndroidStudio Kotlin 的环境: 选择包名,然后右键: 选择Class类型,会有class: 创建CounterCla ...
- hdu 1.3.2 Moving Tables
这道题比较简单,就是用数组存取其路径.如101和102是对门,其过道号可以记为51. 1和2之间的为1. 今早突然收到操作系统停课的通知,哈哈 回来就做一下水题,开心 #include<cst ...
- 为什么在UDP包中不能获取发包方的地址
首先,我们要先了解一下UDP包的结构. 图1 UDP报文格式 从图1,我们可以看出,从UDP包中,我们可以获取的信息只有源端口和目的地端口.我们不能获取到源IP因为报文中没有源IP.真正包含IP地址的 ...