线程,同步与锁

原创 2007年10月02日 16:29:00

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


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)是lock this的意思.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中的SyncBlock Cache区域中的一个SyncBlock.什么意思呢?就是说,当你执行Monitor.Enter(Object)时,如果object的索引值为负数,就从SyncBlock Cache中选区一个SyncBlock,将其地址放在object的索引中。这样就完成了以object为标志的定,其他的线程想再次进行Monitor.Enter(object)操作,将获得object为正数的索引,然后就等待。直到索引变为负数,即线程使用Monitor.Exit(object)将索引变为负数。

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

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

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

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

线程、线程池、并发、同步、异步、锁

线程、线程池、并发、同步、异步、锁先看一个模拟多个线程同时写1000条日志例子:class Program { static void Main(string[] args) { ...
  • nowadaysall
  • nowadaysall
  • 2015年12月21日 15:44
  • 1517

多线程同步锁的使用范例

用一个买票的例子来示范多线程操作一个对象时,同步锁的使用。 如何加锁需要认真思考。...
  • fenggering
  • fenggering
  • 2016年11月14日 23:10
  • 1885

线程同步与互斥:互斥锁

为什么需要互斥锁? 在多任务操作系统中,同时运行的多个任务可能都需要使用同一种资源。这个过程有点类似于,公司部门里,我在使用着打印机打印东西的同时(还没有打印完),别人刚好也在此刻使用打印机打印...
  • lianghe_work
  • lianghe_work
  • 2015年08月18日 09:59
  • 9045

【多线程】线程中的同步锁synchronized

当多个线程同时执行时,由于cpu是随机分片的,所以,一个线程在执行过程中被另一个线程打断的情况是经常发生的。 这在某些情况下是会影响到正常的程序的输出结果的。比如银行转账一个人的账户在转账时是不能允许...
  • wangyy130
  • wangyy130
  • 2016年07月25日 21:23
  • 931

Android多线程-----同步锁

一、同步机制关键字synchronized 对于java来说,最常用的同步机制就是synchronized关键字,他是一种基于语言的粗略锁,能够作用于对象、函数、class。每个对象都...
  • a992036795
  • a992036795
  • 2016年05月11日 10:27
  • 7399

线程同步与互斥:读写锁

读写锁基本原理 当有一个线程已经持有互斥锁时,互斥锁将所有试图进入临界区的线程都阻塞住。但是考虑一种情形,当前持有互斥锁的线程只是要读访问共享资源,而同时有其它几个线程也想读取这个共享资源,但是...
  • lianghe_work
  • lianghe_work
  • 2015年08月19日 09:27
  • 2287

进程间线程间的同步锁原理和种类

同步锁的基本概念: 锁基本都是内核对象,用于控制多线程间多进程间的同步访问。 我们知道进程间的同步操作都是要借助内核来完成的,和同一个进程中的线程同步只需要在用户模式下是有很大差别的,当然,对于进程安...
  • Blues1021
  • Blues1021
  • 2015年03月16日 23:47
  • 4388

java多线程、并发系列之 (synchronized)同步与加锁机制

SynchronizedJava中每个对象都有一个内置锁,当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁。获得一个对象的锁也称为获...
  • yujin753
  • yujin753
  • 2015年04月30日 18:49
  • 8886

Android同步锁:Synchronized的小实验

今天在看博客的时候突然遇到了同步代码块——Synchronized,猛然间想到自己这次面试的时候面试官特意问了关于java线程同步锁的问题,当时自己也是知道那么一点单例模式,就主要聊了下单例模式,而同...
  • qq_33923079
  • qq_33923079
  • 2016年11月28日 22:49
  • 2635

Objective-C中的同步线程的锁

概述在多线程编程中往往会遇到多个线程同时访问共享的资源,这种情况我们需要通过同步线程来避免。也就是给线程加锁。 因为Objective-C是C语言的超集。,严格的来说是真超集。所以C语言当中的pth...
  • GGGHub
  • GGGHub
  • 2016年05月09日 16:01
  • 3118
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:线程,同步与锁
举报原因:
原因补充:

(最多只允许输入30个字)