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的更多相关文章

  1. 重新想象 Windows 8 Store Apps (46) - 多线程之线程同步: Lock, Monitor, Interlocked, Mutex, ReaderWriterLock

    [源码下载] 重新想象 Windows 8 Store Apps (46) - 多线程之线程同步: Lock, Monitor, Interlocked, Mutex, ReaderWriterLoc ...

  2. 【转】多线程:C#线程同步lock,Monitor,Mutex,同步事件和等待句柄(上)

    本篇从Monitor,Mutex,ManualResetEvent,AutoResetEvent,WaitHandler的类关系图开始,希望通过 本篇的介绍能对常见的线程同步方法有一个整体的认识,而对 ...

  3. 【Java并发系列】----JUC之Lock

    显式锁 Lock 在Java 5.0之前,协调共享对象的访问时可以使用的机制只有synchronized和volatile.Java 5.0后增加了一些新的机制,但并不是一种替代内置锁的方法,而是当内 ...

  4. Java并发编程系列-(2) 线程的并发工具类

    2.线程的并发工具类 2.1 Fork-Join JDK 7中引入了fork-join框架,专门来解决计算密集型的任务.可以将一个大任务,拆分成若干个小任务,如下图所示: Fork-Join框架利用了 ...

  5. [转载] java并发编程:Lock(线程锁)

    作者:海子 原文链接: http://www.cnblogs.com/dolphin0520/p/3923167.html 出处:http://www.cnblogs.com/dolphin0520/ ...

  6. java高并发系列 - 第6天:线程的基本操作

    新建线程 新建线程很简单.只需要使用new关键字创建一个线程对象,然后调用它的start()启动线程即可. Thread thread1 = new Thread1(); t1.start(); 那么 ...

  7. java高并发系列 - 第31天:获取线程执行结果,这6种方法你都知道?

    这是java高并发系列第31篇. 环境:jdk1.8. java高并发系列已经学了不少东西了,本篇文章,我们用前面学的知识来实现一个需求: 在一个线程中需要获取其他线程的执行结果,能想到几种方式?各有 ...

  8. java高并发系列 - 第11天:线程中断的几种方式

    java高并发系列第11篇文章. 本文主要探讨一下中断线程的几种方式. 通过一个变量控制线程中断 代码: package com.itsoku.chat05; import java.util.con ...

  9. java高并发系列 - 第10天:线程安全和synchronized关键字

    这是并发系列第10篇文章. 什么是线程安全? 当多个线程去访问同一个类(对象或方法)的时候,该类都能表现出正常的行为(与自己预想的结果一致),那我们就可以所这个类是线程安全的. 看一段代码: pack ...

随机推荐

  1. iscsi: 环境搭建

    组网环境 +----------+---------------+---------------+ | hostname | ip address | iscsi role | +---------- ...

  2. EasyUI Combobox设定默认值

    $(function () { $('#Select6').combobox({ onLoadSuccess: function () { var data = $('#Select6').combo ...

  3. Tomcat部署方式

    tomcat中三种部署项目的方法 第一种方法:在tomcat中的conf目录中,在server.xml中的,<host/>节点中添加: <Context path="/he ...

  4. when you're gone

      when you're gone ——艾薇儿 I always needed time on my own 我真的需要一些独处的时间 I never thought I'd need you th ...

  5. Linux环境中DISPLAY环境变量的解释及设置

    在Linux/Unix类操作系统上的GUI应用程序使用X Window系统(X Window System),它旨在允许多个用户使用窗口化的应用程序通过网络访问计算机. DISPLAY环境变量用来设置 ...

  6. JAVA学习博客----2015.4

    这是开始写的第一篇学习博客,记录一下每个月的学习进度和掌握程度,因为这是第一次写学习博客而且已经看编程方面的书已经有几个月了,所以这一篇学习博客可能看似有些乱或者篇幅太长.从十二月的<程序员教程 ...

  7. C++混合编程之idlcpp教程Lua篇(3)

    上一篇 C++混合编程之idlcpp教程Lua篇(2) 是一个 hello world 的例子,仅仅涉及了静态函数的调用.这一篇会有新的内容. 与LuaTutorial0相似,工程LuaTutoria ...

  8. Visual Stuido 在文件中查找不显示结果

    出现好几次了.解决方法如下: 注册表找到 HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{73B7DC00-F498-4ABD-AB79-D07AFD52F395}\InPr ...

  9. [ASE][Daily Scrum]11.25

    View Shilin Liu 修复现有的bug,子弹无法破坏射程内视野外的墙 Yiming Liao 无法看见从视野外到视野内的子弹     Server Songtao He 服务器处理子弹命中t ...

  10. http://www.cnbeta.com/articles/306769.htm

    事实上,很少有方法可以帮你做到.有些人可能会想到试着把Vim打造成C语言IDE的,比如c.vim:也有把Vim集成到Eclipse里的Eclim .但是我想要告诉你的是一个更加通用的,只用插件实现的方 ...