线程与并发系列一:Lock、Monitor、UserSpinLock
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading; namespace MyConsole.ThreadDemo
{
class Lock
{
static int Storeage { get; set; }
static object LockObject = new object(); static void Main(string[] args)
{
var timer = new Stopwatch();
var my = new Lock();
var data = new Dictionary<string, Action>()
{
{"错误的代码",my.Wrong},
{"正解的代码 使用Lock",my.UserLock},
{"正解的代码 使用Monitor",my.UserMonitor},
{"使用UserSpinLock",my.UserSpinLock},
};
foreach (var item in data)
{
Console.WriteLine();
Console.WriteLine(item.Key);
timer.Restart();
my.Being(new ThreadStart(item.Value));
timer.Stop();
Console.WriteLine(timer.ElapsedTicks);
}
} #region = Wrong =
void Wrong()
{
var random = new Random(DateTime.Now.Millisecond);
var w = random.Next();
Lock.Storeage = w;
Thread.Sleep(random.Next(, ));
var r = Lock.Storeage; Message(w, r);
}
#endregion #region = UserLock =
void UserLock()
{
var random = new Random(DateTime.Now.Millisecond);
var w = random.Next();
var r = -;
lock (LockObject)
{
Lock.Storeage = w;
Thread.Sleep(random.Next(, ));
r = Lock.Storeage;
} Message(w, r);
}
#endregion #region = UserMonitor =
void UserMonitor()
{
var random = new Random(DateTime.Now.Millisecond);
var w = random.Next();
var r = -;
Monitor.Enter(LockObject); Lock.Storeage = w;
Thread.Sleep(random.Next(, ));
r = Lock.Storeage;
Monitor.Exit(LockObject); Message(w, r);
}
#endregion #region = UserSpinLock =
SpinLock _spinlock = new SpinLock();
void UserSpinLock()
{
var random = new Random(DateTime.Now.Millisecond);
var w = random.Next();
var r = -;
var lockTaken = false;
_spinlock.Enter(ref lockTaken); Lock.Storeage = w;
Thread.Sleep(random.Next(, ));
r = Lock.Storeage;
_spinlock.Exit(); Message(w, r);
}
#endregion #region = Being =
void Being(ThreadStart start)
{
var threads = Enumerable.Range(, ).Select(x => new Thread(start)).ToList();//必须ToList一下
foreach (var item in threads)
{
item.Start();
} foreach (var item in threads)
{
item.Join();
}
}
#endregion #region - Message -
static void Message(int w, int r)
{
var msg = string.Format("线程{0}在运行 存入{1} 读出{2} {3}",
Thread.CurrentThread.ManagedThreadId, r, w,
r == w ? "正确" : "错误");
Console.WriteLine(msg);
}
#endregion
}
}
输出
错误的代码
线程5在运行 存入99 读出95 错误
线程4在运行 存入99 读出95 错误
线程6在运行 存入99 读出47 错误
线程3在运行 存入99 读出43 错误
线程8在运行 存入99 读出47 错误
线程7在运行 存入99 读出47 错误
线程9在运行 存入99 读出47 错误
线程10在运行 存入99 读出47 错误
线程12在运行 存入99 读出99 正确
线程11在运行 存入99 读出99 正确 正解的代码 使用Lock
线程13在运行 存入8 读出8 正确
线程14在运行 存入61 读出61 正确
线程16在运行 存入61 读出61 正确
线程15在运行 存入61 读出61 正确
线程18在运行 存入65 读出65 正确
线程17在运行 存入13 读出13 正确
线程20在运行 存入17 读出17 正确
线程19在运行 存入65 读出65 正确
线程22在运行 存入22 读出22 正确
线程21在运行 存入70 读出70 正确 正解的代码 使用Monitor
线程23在运行 存入90 读出90 正确
线程25在运行 存入90 读出90 正确
线程24在运行 存入90 读出90 正确
线程27在运行 存入95 读出95 正确
线程26在运行 存入95 读出95 正确
线程29在运行 存入56 读出56 正确
线程31在运行 存入65 读出65 正确
线程28在运行 存入52 读出52 正确
线程30在运行 存入61 读出61 正确
线程32在运行 存入70 读出70 正确 使用UserSpinLock
线程33在运行 存入19 读出19 正确
线程40在运行 存入24 读出24 正确
线程41在运行 存入76 读出76 正确
线程35在运行 存入71 读出71 正确
线程34在运行 存入19 读出19 正确
线程38在运行 存入24 读出24 正确
线程39在运行 存入24 读出24 正确
线程36在运行 存入71 读出71 正确
线程37在运行 存入24 读出24 正确
线程42在运行 存入76 读出76 正确
线程与并发系列一:Lock、Monitor、UserSpinLock的更多相关文章
- 重新想象 Windows 8 Store Apps (46) - 多线程之线程同步: Lock, Monitor, Interlocked, Mutex, ReaderWriterLock
[源码下载] 重新想象 Windows 8 Store Apps (46) - 多线程之线程同步: Lock, Monitor, Interlocked, Mutex, ReaderWriterLoc ...
- 【转】多线程:C#线程同步lock,Monitor,Mutex,同步事件和等待句柄(上)
本篇从Monitor,Mutex,ManualResetEvent,AutoResetEvent,WaitHandler的类关系图开始,希望通过 本篇的介绍能对常见的线程同步方法有一个整体的认识,而对 ...
- 【Java并发系列】----JUC之Lock
显式锁 Lock 在Java 5.0之前,协调共享对象的访问时可以使用的机制只有synchronized和volatile.Java 5.0后增加了一些新的机制,但并不是一种替代内置锁的方法,而是当内 ...
- Java并发编程系列-(2) 线程的并发工具类
2.线程的并发工具类 2.1 Fork-Join JDK 7中引入了fork-join框架,专门来解决计算密集型的任务.可以将一个大任务,拆分成若干个小任务,如下图所示: Fork-Join框架利用了 ...
- [转载] java并发编程:Lock(线程锁)
作者:海子 原文链接: http://www.cnblogs.com/dolphin0520/p/3923167.html 出处:http://www.cnblogs.com/dolphin0520/ ...
- java高并发系列 - 第6天:线程的基本操作
新建线程 新建线程很简单.只需要使用new关键字创建一个线程对象,然后调用它的start()启动线程即可. Thread thread1 = new Thread1(); t1.start(); 那么 ...
- java高并发系列 - 第31天:获取线程执行结果,这6种方法你都知道?
这是java高并发系列第31篇. 环境:jdk1.8. java高并发系列已经学了不少东西了,本篇文章,我们用前面学的知识来实现一个需求: 在一个线程中需要获取其他线程的执行结果,能想到几种方式?各有 ...
- java高并发系列 - 第11天:线程中断的几种方式
java高并发系列第11篇文章. 本文主要探讨一下中断线程的几种方式. 通过一个变量控制线程中断 代码: package com.itsoku.chat05; import java.util.con ...
- java高并发系列 - 第10天:线程安全和synchronized关键字
这是并发系列第10篇文章. 什么是线程安全? 当多个线程去访问同一个类(对象或方法)的时候,该类都能表现出正常的行为(与自己预想的结果一致),那我们就可以所这个类是线程安全的. 看一段代码: pack ...
随机推荐
- 第一章 Mybtais的两种启动方式
Mybatis的两种启动方式如下: 1.xml实现: xml的实现方式中,主要是通过手动创建SqlSession,然后调用session.selectOne()方法实现来实现. 首先是创建Config ...
- VS2013使用rtklib中需要注意的一些问题(编译)
最近因为项目需要需要对rtcm数据进行解码,rtklib提供了很多底层的函数,准备直接输出标准DLL的方式供C#调用.下面把项目中引用rtklib源码需要注意的地方记录下. 1. 首先在vs2013中 ...
- [转]Theano下用CNN(卷积神经网络)做车牌中文字符OCR
Theano下用CNN(卷积神经网络)做车牌中文字符OCR 原文地址:http://m.blog.csdn.net/article/details?id=50989742 之前时间一直在看 Micha ...
- sqlite中的replace、insert、update之前的区别
本文转自http://www.ithao123.cn/content-933827.html,在此感谢作者 android数据库操作,有两种方式,一种用android提供给我们的数据库操作函数inse ...
- tar 打包命令
Usage: tar -[cxtzjhmvO] [-X FILE] [-T FILE] [-f TARFILE] [-C DIR] [FILE]... Create, extract, or list ...
- [vb.net]最简单的邮件发送
Imports Microsoft.Office.Interop.Outlook Private Sub sendMail() Dim outObj As New Application Dim it ...
- 【转】移动端viewport的使用
web端网站转移至移动端页面,注意点如下: 1.首先引入viewport调整页面宽度 <meta name="viewport" content="width=de ...
- Linux下使用RecordMyDesktop进行屏幕录像
近期我们在评估给用户提供视频教程的可能性,以此来展示某些用视频才能更好表达的教程.在挖掘这个问题的时候,我们发现极丰富的可用于屏幕录像的工具.这些程序大体上特性的区别有:视频质量,性能,兼容性.这在此 ...
- LDO-XC6216C202MR-G
XC6216C202MR-G 1.改产品是特瑞士(TOREX)公司电源管理芯片,输入电压可达28V,输出可调23V,最大输出电流150mA.压差最小为300mV.该系列有固定式输出和可调式 ...
- 重启EBS
http://www.cnblogs.com/toowang/archive/2012/03/28/2421275.html 概述步骤(此操作没有停止数据库): 1.登陆FTP,终止应用:cd $CO ...