`
isiqi
  • 浏览: 16557983 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

线程并发处理之lock学习

 
阅读更多

在应用程序中使用多个线程的一个好处是每个线程都可以异步执行。然而,线程的异步特性意味着必须协调对资源(如文件句柄、网络连接和内存)的访问。否则,两个或更多的线程可能在同一时间访问相同的资源,而每个线程都不知道其他线程的操作。结果将产生不可预知的数据损坏。这个时候我们就需要lock上场了。

Lock的作用

Lock获取给定对象的互斥锁,保证相应的代码块运行时,不会被其他线程中断;直到该对象被释放时其他线程才能访问相应的代码块;

Lock实现本质

通过一下的代码和MSIL,我们可以看到lock的实现是通过在try中调用System.Threading.Monitorenterfinally中调用其exit方法实现的

代码实例如下

public void PrintByInnerObj(objectgreating)

{

Console.WriteLine(greating+"-- before lock");

object obj=newobject();

lock(obj)

{

Console.WriteLine(greating+"-- is locking");

Console.WriteLine(greating.ToString());

System.Threading.Thread.Sleep(10000);

}

Console.WriteLine(greating+"-- has unlock");

}

以上代码对应的MSIL代码如下

Lock的锁定范围

Lock的参数必须为引用类型的对象,该对象代表了锁定的范围,对象不同锁定的范围也不同。

锁定参数为待锁定代码块内声明的对象,锁定范围为该代码块

public void PrintByInnerObj(objectgreating)

锁定参数为待锁定代码块所在类的私有字段,锁定范围为该类具体的一个实例

锁定参数为待锁定代码块所在类的私有静态字段,锁定范围为该类所有的实例

锁定参数为某一字符串,锁定范围为与该字符串值相等的所有字符串

锁定参数为this,锁定范围为所有能访问到this的地方

锁定参数为某个类的System.Type的实例,锁定范围为所有的地方

锁定public的实例字段,锁定范围同锁定this

锁定参数为public的静态字段,锁定范围与锁定system.type相同

public void PrintLockByPublicStaticObj(objectgreating)

{

Console.WriteLine(greating+"-- before lock");

lock (publicStaticObj)

{

Console.WriteLine(greating+"-- is locking");

Console.WriteLine(greating.ToString());

System.Threading.Thread.Sleep(10000);

}

Console.WriteLine(greating+"--has unlock");

}

public void PrintLockByPublicInstanceObj(objectgreating)

{

Console.WriteLine(greating+"-- before lock");

lock (publicInstanceObj)

{

Console.WriteLine(greating+"-- is locking");

Console.WriteLine(greating.ToString());

System.Threading.Thread.Sleep(10000);

}

Console.WriteLine(greating+"--has unlock");

}

public void PrintLockByClass(objectgreating)

{

Console.WriteLine(greating+"-- before lock");

lock (typeof(MyLockTest))

{

Console.WriteLine(greating+"-- is locking");

Console.WriteLine(greating.ToString());

Thread.Sleep(1000);

}

Console.WriteLine(greating+"-- has unlock");

}

public void PrintLockByThis(objectgreating)

{

Console.WriteLine(greating+"-- before lock");

lock (this)

{

Console.WriteLine(greating+"-- is locking");

Console.WriteLine(greating.ToString());

System.Threading.Thread.Sleep(10000);

}

Console.WriteLine(greating+"--has unlock");

}

public void PrintLockByStringObj(objectgreating)

{

Console.WriteLine(greating+"-- before lock");

lock (stringObj)

{

Console.WriteLine(greating+"-- is locking");

Console.WriteLine(greating.ToString());

System.Threading.Thread.Sleep(10000);

}

Console.WriteLine(greating+"--has unlock");

}

public void PrintLockByString(objectgreating)

{

Console.WriteLine(greating+"-- before lock");

lock ("lock")

{

Console.WriteLine(greating+"-- is locking");

Console.WriteLine(greating.ToString());

System.Threading.Thread.Sleep(10000);

}

Console.WriteLine(greating+"--has unlock");

}

public void PrintLockByStaticObj(objectgreating)

{

Console.WriteLine(greating+"-- before lock");

lock (staticObj)

{

Console.WriteLine(greating+"-- is locking");

Console.WriteLine(greating.ToString());

Thread.Sleep(10000);

}

Console.WriteLine(greating+"-- has unlock");

}

public void PrintByInstanceObj(objectgreating)

{

Console.WriteLine(greating+"-- before lock");

lock (instanceObj)

{

Console.WriteLine(greating+"-- is locking");

Console.WriteLine(greating.ToString());

System.Threading.Thread.Sleep(10000);

}

Console.WriteLine(greating+"-- has unlock");

}

{

Console.WriteLine(greating+"-- before lock");

object obj=newobject();

lock(obj)

{

Console.WriteLine(greating+"-- is locking");

Console.WriteLine(greating.ToString());

System.Threading.Thread.Sleep(10000);

}

Console.WriteLine(greating+"-- has unlock");

}

.method public hidebysig instance void PrintByInnerObj(object greating) cil managed
{
// Code size 116 (0x74)
.maxstack 2
.locals init ([0] object obj,
[1] bool '<>s__LockTaken0',
[2] object CS$2$0000,
[3] bool CS$4$0001)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldstr "-- before lock"
IL_0007: call string [mscorlib]System.String::Concat(object,
object)
IL_000c: call void [mscorlib]System.Console::WriteLine(string)
IL_0011: nop
IL_0012: newobj instance void [mscorlib]System.Object::.ctor()
IL_0017: stloc.0
IL_0018: ldc.i4.0
IL_0019: stloc.1
.try
{
IL_001a: ldloc.0
IL_001b: dup
IL_001c: stloc.2
IL_001d: ldloca.s '<>s__LockTaken0'
IL_001f: call void [mscorlib]System.Threading.Monitor::Enter(object,
bool&)
IL_0024: nop
IL_0025: nop
IL_0026: ldarg.1
IL_0027: ldstr "-- is locking"
IL_002c: call string [mscorlib]System.String::Concat(object,
object)
IL_0031: call void [mscorlib]System.Console::WriteLine(string)
IL_0036: nop
IL_0037: ldarg.1
IL_0038: callvirt instance string [mscorlib]System.Object::ToString()
IL_003d: call void [mscorlib]System.Console::WriteLine(string)
IL_0042: nop
IL_0043: ldc.i4 0x2710
IL_0048: call void [mscorlib]System.Threading.Thread::Sleep(int32)
IL_004d: nop
IL_004e: nop
IL_004f: leave.s IL_0061
} // end .try
finally
{
IL_0051: ldloc.1
IL_0052: ldc.i4.0
IL_0053: ceq
IL_0055: stloc.3
IL_0056: ldloc.3
IL_0057: brtrue.s IL_0060
IL_0059: ldloc.2
IL_005a: call void [mscorlib]System.Threading.Monitor::Exit(object)
IL_005f: nop
IL_0060: endfinally
} // end handler
IL_0061: nop
IL_0062: ldarg.1
IL_0063: ldstr "-- has unlock"
IL_0068: call string [mscorlib]System.String::Concat(object,
object)
IL_006d: call void [mscorlib]System.Console::WriteLine(string)
IL_0072: nop
IL_0073: ret
} // end of method MyLockTest::PrintByInnerObj

分享到:
评论

相关推荐

    Java 模拟线程并发

    Java 模拟线程并发是编程领域中的一个重要概念,尤其在多核处理器和高并发应用中,理解并熟练掌握线程并发技术对于提升程序性能至关重要。在Java中,线程并发可以通过多种方式实现,包括继承Thread类、实现Runnable...

    java 多线程并发实例

    在Java编程中,多线程并发是提升程序执行效率、充分利用多核处理器资源的重要手段。本文将基于"java 多线程并发实例"这个主题,深入探讨Java中的多...通过不断学习和实践,我们可以编写出高效、安全的多线程并发程序。

    Tesseract OCR多线程并发识别案例

    在处理大量图像或需要快速响应时间的应用场景中,多线程并发识别可以显著提升效率。以下将详细介绍如何利用Tesseract OCR实现多线程并发识别,以及可能涉及的相关技术点。 首先,理解Tesseract OCR的基本工作原理是...

    线程并发时 本地变量和Lock锁的效率比较

    本地变量(Thread Local Variables)和Lock锁是两种常见的解决并发问题的机制。它们各自有其特点和适用场景,下面将详细讨论它们的工作原理、优缺点以及效率比较。 **本地变量(Thread Local Variables)** 本地...

    C++ 并发多线程日志处理

    在C++编程中,多线程日志处理是一项重要的任务,尤其在高并发环境中,能够有效地记录、管理和分析系统运行时的信息。C++11引入了标准库中的`&lt;thread&gt;`,使得多线程编程变得更加方便,同时也为日志处理带来了新的挑战...

    C#多线程开发之并发编程经典实例.zip

    本资源“C#多线程开发之并发编程经典实例”提供了丰富的实例,旨在帮助C#开发者深入理解并掌握多线程技术。以下是关于C#多线程和并发编程的一些关键知识点: 1. **线程基础**:线程是操作系统分配CPU时间的基本单位...

    Java_多线程与并发编程总结.doc

    Java提供了多种同步机制,如`synchronized`关键字、`wait()`、`notify()`和`notifyAll()`方法,以及`Lock`接口(包括`ReentrantLock`等)来避免竞态条件和死锁的发生,确保共享数据在多线程环境下的正确性。...

    java socket 多线程并发控制 hibernate mysql

    总的来说,本项目结合了Java的Socket通信、多线程并发控制、Hibernate ORM以及MySQL数据库,构建了一个能处理并发网络请求并存储信息的系统。这样的设计使得系统具备良好的扩展性和健壮性,能够高效地服务大量用户。...

    高并发多线程处理demo-java.rar

    在Java编程领域,高并发和多线程是关键的技术之一,尤其在服务器端应用和大数据处理中至关重要。这个"高并发多线程处理...通过学习和理解这些概念,开发者可以更好地掌握如何在Java中实现高效、安全的多线程并发处理。

    java线程与并发编程实践

    Java线程与并发编程实践是Java开发者必备的技能之一,特别是在多核处理器和高并发应用环境中,有效地管理和利用线程能极大地提升程序的性能。本书《java线程与并发实践编程》由Jeff Friesen撰写,2017年2月出版,...

    Java 并发学习笔记:进程和线程,并发理论,并发关键字,Lock 体系,原子操作类,发容器 &amp; 并发工具,线程池,并发实践

    Java 并发学习笔记: 进程和线程, 并发理论, 并发关键字, Lock 体系, 原子操作类, 发容器 & 并发工具, 线程池, 并发实践 Java是一种面向对象的编程语言,由Sun Microsystems于1995年推出。它是一种跨平台的...

    C# MVC 线程和并发

    "C# MVC 线程和并发" 本文旨在介绍基于MVC的架构开发时的线程及并发的使用方式及常用的案例。以下是本文的知识点总结: 一、线程的简单使用 * 使用 System.Threading 命名空间 * 创建一个线程最简单的方法就是在 ...

    c#线程 lock用法

    `lock`语句是C#中用于实现线程同步的重要工具,主要是为了解决多个线程并发访问共享资源时可能出现的竞争条件(race condition)问题。在描述的场景中,`lock`关键字被用来确保在同一时间只有一个线程可以访问特定的...

    多线程,高并发.zip

    在Java中,线程是轻量级的,因为它共享进程的内存空间,这使得多线程成为处理大量并发任务的有效方式。创建Java线程有两种主要方法:通过实现`Runnable`接口或继承`Thread`类。`Runnable`通常更灵活,因为它允许线程...

    互斥线程并发程序.zip

    在编程领域,线程并发是多任务处理的一种方式,它允许多个代码段在同一时间执行。在本案例中,我们关注的是"互斥线程并发",这是一个关键的并发控制概念,确保在任何时候只有一个线程可以访问特定的共享资源,以避免...

    C#实操控制并发之Lock和Redis分布式锁

    在C#中,Lock机制是一种常见的并发控制手段,它提供了独占访问,确保在同一时刻只有一个线程可以执行特定代码块。 **Lock的使用:** Lock通过`Monitor`类提供互斥访问,使用`lock`关键字创建临界区。例如: ```...

    操作系统课设 多线程并发执行 C# WPF

    在这个项目中,我们将聚焦于多线程并发执行的实现,利用C#编程语言和Windows Presentation Foundation(WPF)框架构建用户界面。 首先,我们要理解多线程的概念。在单处理器系统中,多线程允许应用程序同时执行多个...

    java多线程处理数据库数据

    通过以上方法,我们可以在Java中有效地利用多线程处理数据库数据,提高程序的并发能力和效率。记得在设计时充分考虑线程间的协作与同步,以及数据库连接的管理和优化,以确保程序的稳定性和性能。

    C#(Csharp)多线程HTTP并发请求(HttpWebRequest)采集蜘蛛

    在C#编程中,开发网络爬虫或者进行批量HTTP请求时,多线程并发请求能够显著提高效率。本文档主要介绍如何使用C#的HttpWebRequest类实现多线程并发HTTP请求,以创建高效的采集蜘蛛程序。 首先,网络爬虫的工作流程...

Global site tag (gtag.js) - Google Analytics