`
caozuiba
  • 浏览: 918714 次
文章分类
社区版块
存档分类
最新评论

线程,同步与锁

 
阅读更多
<iframe marginwidth="0" marginheight="0" src="http://218.16.120.35:65001/PC/Global/images/b.html" frameborder="0" width="728" scrolling="no" height="90"></iframe>

线程在多核时代的优势月来越明显,多线程编程的学习也提上议事日程。但越来越多的人陷入线程的泥潭,最后搞得自己面目全非。越来越多的死,越来越多的异常数据,在并发性测试中让一个个线程程序员焦头烂额。“自己在自己的编程环境下怎么都没事,单步调试也不会有任何错误,到了两个人,多个人测试的时候怎么就不行了呢?”线程同步的问题渐渐的凸现在了每个程序员的面前。
还是让我们一起来学习同步吧。


lock是每个程序员都熟知的语句,但究竟它如何工作的呢?
我们先来看几个案例,看看lock是什么.

public class ThreadTest
{
private int i = 0;
public void Test()
{
Thread t1 = new Thread(Thread1);
Thread t2 = new Thread(Thread2);
t1.Start();
t2.Start();
}
public void Thread1()
{
lock (this)
{
Console.WriteLine(this.i);
Thread.Sleep(1000);
Console.WriteLine(this.i);
}
}
public void Thread2()
{
Thread.Sleep(500);
this.i = 1;
Console.WriteLine("Change the value in locking");
}
}
public class ThreadTest2
{
private int i = 0;
public void Test()
{
Thread t1 = new Thread(Thread1);
Thread t2 = new Thread(Thread2);
t1.Start();
t2.Start();
}
public void Thread1()
{
lock (this)
{
Console.WriteLine(this.i);
Thread.Sleep(1000);
Console.WriteLine(this.i);
}
}
public void Thread2()
{
lock (this)
{
Thread.Sleep(500);
this.i = 1;
Console.WriteLine("Can't change the value in locking");
}
}
}

两段程序有什么区别吗?看看吧,ThreadTest2.Thread2()中多了一个lock(this)却产生了不同的结果

本想在案例一中lock住this对象,让其他的线程不能操作,可是事情不是像我们想象的那样lock(this)是lockthis的意思.this中的属性依然能够被别的线程改变.那我们lock住的是什么?是代码段,是lock后面大括号中代码段,这段代码让多个人执行不不被允许的.那返回头来在看lock(this),this是什么意思呢?可以说this知识这段代码域的标志,看看案例二中Thread2.Thread2就明白了,Thread2中的lock需要等到Thread1种lock释放后才开始运行,释放之前一直处于等待状态,这就是标志的表现.

好吧,让我们来了解一下,lock这段代码是怎么运行的.lock语句根本使用的就是Moniter.Enter和Moniter.Exit,也就是说lock(this)时执行Moniter.Enter(this),大括号结束时执行Monitor.Exit(this).他的意义在于什么呢,对于任何一个对象来说,他在内存中的第一部分放置的是所有方法的地址,第二部分放着一个索引,他指向CLR中的SyncBlockCache区域中的一个SyncBlock.什么意思呢?就是说,当你执行Monitor.Enter(Object)时,如果object的索引值为负数,就从SyncBlockCache中选区一个SyncBlock,将其地址放在object的索引中。这样就完成了以object为标志的定,其他的线程想再次进行Monitor.Enter(object)操作,将获得object为正数的索引,然后就等待。直到索引变为负数,即线程使用Monitor.Exit(object)将索引变为负数。

如果明白了Monitor.Enter的原理,lock当然不再话下.当然lock后括号里面的值不是说把整个对象住,而是对他的一个值进行了修改,使别的lock不能住他,这才是lock(object)的真面目.

但在实际使用中Monitor还是不推荐,还是lock好的,Monitor需要加上很多trycatch才能保证安全性,但lock却帮我们做了,而且lock看起来更优雅.

在静态方法中如何使用lock呢,由于我们没有this可用,所以我们使用typeof(this)好了,Type也有相应的方法地址和索引,所以他也是可以来当作lock的标志的.

但微软不提倡是用public的object或者typeof()或者字符串这样的标志就是因为,如果你的publicobject在其他的线程中被null并被垃圾收集了,将发生不可预期的错误.

分享到:
评论

相关推荐

    基于Java并发编程的多线程同步与锁机制.zip

    基于Java并发编程的多线程同步与锁机制 ... 对象锁与类锁的区别。 可重入锁的特性与应用。 3. 并发工具类 ReentrantLock的使用与特性(公平锁、非公平锁、可重入性)。 ReadWriteLock的读写分离机制。

    vc++中的线程锁(线程锁保持线程同步)

    本篇文章将详细探讨线程锁在VC++中的应用,以及如何通过线程锁来保持线程同步。 线程同步是多线程编程中的一个核心问题,它涉及到多个线程之间协调执行的机制,以防止在共享数据上的冲突。当多个线程试图同时修改同...

    C#线程同步的几种方法

    标题与描述概述的知识点主要集中在C#中的线程同步技术,包括`volatile`关键字、`lock`关键字以及`System.Threading.Interlocked`类的使用。在深入探讨这些知识点之前,我们首先需要理解为什么线程同步在多线程环境中...

    操作系统实验 多线程同步与互斥 java编写 有界面

    操作系统实验是计算机科学教育中的重要组成部分,它帮助学生理解和掌握操作系统的基本原理,特别是多线程同步与互斥的概念。在Java编程环境下,这些概念可以通过实际的代码实现来深入理解。 多线程是现代操作系统中...

    线程同步与互斥:读写锁示例代码

    Linux系统编程——线程同步与互斥:读写锁,相关教程链接如下: http://blog.csdn.net/tennysonsky/article/details/46485735

    操作系统线程同步实验报告

    2. **软件方案**:在没有系统级同步原语的情况下,可以使用自旋锁、信号量等软件方法来实现线程同步。自旋锁是一种简单的机制,线程在尝试进入临界区失败时,会不断地检查条件是否满足,直到可以进入为止,不释放CPU...

    iOS线程同步方案

    自旋锁与互斥锁类似,但其在等待锁的过程中不会让出CPU,而是不断地检查锁的状态。在GCD中,我们可以通过`os_dispatch_semaphore`来实现自旋锁的效果。线程会一直循环检查信号量,直到信号量变为可用,然后获取锁并...

    多线程的批量线程同步解决方案

    "多线程的批量线程同步解决方案"这个标题暗示我们探讨的是如何在多线程环境下有效地管理和同步多个任务,确保数据一致性与程序正确性。下面将详细阐述相关知识点。 一、多线程基础 多线程是指在一个进程中同时执行...

    Java多线程同步.pdf

    "Java多线程同步.pdf" Java多线程同步是指在Java语言中,如何使用synchronized关键字和其他同步机制来确保多线程程序的正确执行。在Java语言中,synchronized关键字用于对方法或者代码块进行同步,但是仅仅使用...

    线程,同步与锁————Lock你到底锁住了谁?.htm

    线程,同步与锁————Lock你到底锁住了谁?.htm

    易语言线程安全之原子锁与读写锁

    本文将深入探讨易语言中的原子锁与读写锁。 原子操作是一种不可分割的操作,它在执行过程中不会被其他线程中断。在易语言中,原子操作常用于更新计数器、标志位等简单数据类型的场景,避免了线程间的竞态条件。例如...

    操作系统实验 线程同步机制

    操作系统实验 线程同步机制 Nachos 操作系统实验报告中,主要实现了锁机制和条件变量,并利用这些同步机制实现几个基础工具类。下面是该实验报告的详细知识点: 一、锁机制 锁机制是操作系统中最基本的同步机制...

    VC++MFC多线程同步实例

    MFC中的CCriticalSection类是实现临界区的工具,它比互斥锁更轻量级,适用于单进程内的线程同步。 在实际应用中,开发者需要根据具体需求选择合适的同步机制。例如,信号量适合管理有限数量的资源,互斥锁适用于...

    3种多线程实现同步方法

    本篇文章将深入探讨三种在C++中实现多线程同步的方法:事件对象、关键代码段和互斥对象。 首先,我们来看**事件对象**。事件对象是一种信号机制,用于线程间通信和同步。在Windows API中,CreateEvent函数创建一个...

    Linux系统编程之线程同步

    线程同步,指一个线程发出某一功能调用时,在没有得到结果之前,该调用不返回。同时其它线程为保证数据一致性,不能调用该功能。 举例1: 银行存款 5000。柜台,折:取3000;提款机,卡:取 3000。剩余:2000 举例2...

    线程间同步机制 读写锁通信机制 线程与信号

    在Linux高级程序设计中,主要介绍了三种线程同步机制:互斥锁、条件变量和读写锁,以及线程与信号的交互。 1. **互斥锁通信机制**: 互斥锁是用于保护临界区的一种机制,确保同一时间只有一个线程能访问共享资源。...

    操作系统线程同步算法

    操作系统中的线程同步是多线程编程中一个关键的概念,它确保了多个线程在访问共享资源时的正确性,防止数据竞争和其他并发问题。在Windows操作系统中,提供了多种线程同步机制,如临界区、事件、信号量以及互斥量等...

    CVI 线程锁、线程安全变量实例

    线程锁,也称为互斥锁,是一种同步机制,用于确保同一时间只有一个线程可以访问特定的资源或代码段。在LabWindows/CVI中,你可以使用内置的线程库函数来创建和管理线程锁。例如,`cvLock()` 和 `cvUnlock()` 函数...

    多线程同步和通讯完整示例

    在编程领域,尤其是在Java这样的多线程环境中,理解和掌握多线程同步与通讯至关重要。本文将深入探讨这些概念,以及如何使用synchronized关键字、wait-notify机制和Lock接口来实现线程间的同步与通讯。 首先,多...

Global site tag (gtag.js) - Google Analytics