悲观的并发策略——synchronized互斥锁

标签: java 并发 线程 synchronized 互斥锁
421人阅读 评论(0) 收藏 举报

互斥锁是最常见的同步手段,在并发过程中,当多条线程对同一个共享数据竞争时,它保证共享数据同一时刻只能被一条线程使用,其他线程只有等到锁释放后才能重新进行竞争。

对于Java开发人员,最熟悉的肯定就是用synchronized关键词完成锁功能,在涉及到多线程并发时,对于一些变量,你应该会毫不犹豫地加上synchronized去保证变量的同步性。

在C/C++中可直接使用操作系统提供的互斥锁实现同步和线程的阻塞和唤起,与之不同的是,Java要把这些底层封装,而synchronized就是一个典型的互斥锁,同时它也是一个JVM级别的锁,它的实现细节全部封装在JVM中实现,对开发人员只提供了synchronized关键词。

根据锁的颗粒度,可以用synchronized对一个变量、一个方法、一个对象和一个类等加锁。被synchronized修饰的程序块经过编译后,会在前后生成monitorenter和monitorexit两个字节码指令,其中涉及到锁定和解锁对象的确定,这就要根据synchronized来确定了,假如明确指定了所对象,例如synchronized(变量)、synchronized(this)等,说明加解锁对象为变量或运行时对象。假如没有明确指定对象,则根据synchronized修饰的方法去找对应的锁对象,如修饰一个非静态方法表示此方法对应的对象为锁对象,如修饰一个静态方法则表示此方法对应的类对象为锁对象。当一个对象被锁住时,对象里面所有用synchronized修饰的方法都将产生堵塞,而对象里非synchronized修饰的方法可正常被调用,不受锁影响。

为了实现互斥锁,JVM的monitorenter和monitorexit字节码依赖底层操作系统的互斥锁来实现,Java层面的线程与操作系统的原生线程有映射关系,这时如果要将一个线程进行阻塞或唤起都需要操作系统的协助,需要从用户态切换到内核态来执行,这种切换代价十分昂贵,需要消耗很多处理器时间。如果可能,应该减少这样的切换,JVM一般会采取一些措施进行优化,例如在把线程进行阻塞操作之前先让线程自旋等待一段时间,可能在等待期间其他线程已经解锁,这时就无需再让线程执行阻塞操作,避免了用户态到内核态的切换。

Synchronized还有另外一个重要的特性——可重入性。这个特性主要是针对当前线程而言的,可重入即是自己可以再次获得自己的内部锁,在尝试获取对象锁时,如果当前线程已经拥有了此对象的锁,则把锁的计数器加一,在释放锁时则对应地减一,当锁计数器为0时表示锁完全被释放,此时其他线程可对其加锁。可重入特性是为了解决自己锁死自己的情况,如下面伪代码:

public class DeadLock{
    public synchronized void method1(){}
    public synchronized void method2(){
        this.method1();
    }
    public static void main(String[] args){
        DeadLock deadLock=new DeadLock();
        deadLock.method2();
    }
}

这种情况其实也并非不常见,一个类中的同步方法调用另一个同步方法,假如synchronized不支持重入,进入method2方法时当前线程将尝试获取deadLock对象的锁,而method2方法里面执行method1方法时,当前线程又要去尝试获取deadLock对象的锁,这时由于不支持重入,它要去等deadLock对象的锁释放,把自己阻塞了,这就是自己锁死自己的现象。所以重入机制的引入,杜绝了这种情况的发生。

synchronized实现的是一个非公平锁,非公平主要表现在获取锁的行为上,并非是按照申请锁的时间前后给等待线程分配锁的,每当锁被释放后,任何一个线程都有机会竞争到锁,这样做的目的是为了提高执行性能,当然也会产生线程饥饿现象。

synchronized最后一个特性(缺点)就是不可中断性,在所有等待的线程中,你们唯一能做的就是等,而实际情况可能是有些任务等了足够久了,我要取消此任务去干别的事情,此时synchronized是无法帮你实现的,它把所有实现机制都交给了JVM,提供了方便的同时也体现出了自己的局限性。

————-推荐阅读————

我的2017文章汇总——机器学习篇

我的2017文章汇总——Java及中间件

我的2017文章汇总——深度学习篇

我的2017文章汇总——JDK源码篇

我的2017文章汇总——自然语言处理篇

我的2017文章汇总——Java并发篇

——————广告时间—————-

跟我交流,向我提问:

这里写图片描述

公众号的菜单已分为“分布式”、“机器学习”、“深度学习”、“NLP”、“Java深度”、“Java并发核心”、“JDK源码”、“Tomcat内核”等,可能有一款适合你的胃口。

为什么写《Tomcat内核设计剖析》

欢迎关注:

这里写图片描述

查看评论

悲观的并发策略——Synchronized互斥锁

volatile既然不足以保证数据同步,那么就必须要引入锁来确保。互斥锁是最常见的同步手段,在并发过程中,当多条线程对同一个共享数据竞争时,它保证共享数据同一时刻只能被一条线程使用,其他线程只有等到锁...
  • wangyangzhizhou
  • wangyangzhizhou
  • 2014-09-05 19:02:12
  • 3680

高并发控制解决方案乐观并发控制和悲观并发控制总结

概述:我们可以使用两种形式的并发控制策略:乐观并发控制和悲观并发控制。         假设martin和David同时都要编辑Customer文件。如果使用乐观锁策略,他们两个人都能得到一份文件的C...
  • zy41796745
  • zy41796745
  • 2010-04-21 18:53:00
  • 1798

Java并发编程规则:synchronized-锁机制

前面说过的,即使是线程安全的类,也不一定就是线程安全的。当一个不变约束涉及多个变量时,变量间不是彼此独立的:某个变量的值会制约其他变量的值。因此更新一个变量的时候,要在同一原子操作中更新其他变量的值。...
  • boonya
  • boonya
  • 2016-12-08 14:17:59
  • 620

java挑战高并发(8):使用synchronized获取互斥锁的几点说明

在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访问对象并要求操作相同资源时,分割了原子操作就有可能出现数据的不一致或数据不完整的情况,为避免这种情况的发生,我们会采取同步机制,以确...
  • A1023824314
  • A1023824314
  • 2016-08-02 00:13:06
  • 2644

java并发编程---synchronized和lock两种锁的比较

性能比较     在JDK1.5中,synchronized是性能低效的。因为这是一个重量级操作,它对性能最大的影响是阻塞的是实现,挂起线程和恢复线程的操作都需要转入内核态中完成,这些操作给系统的并...
  • u012470138
  • u012470138
  • 2016-12-06 11:27:42
  • 3039

Hibernate中的悲观锁定和乐观锁定

锁定是为了防止多线程对同一记录进行修改时引起的数据混乱.分为两种锁定:悲观锁定和乐观锁定乐观锁定  在持久类中加入一个数值型version属性,在持久类对应的表中有一个名为version的列和该持久类...
  • daryl715
  • daryl715
  • 2007-02-12 13:52:00
  • 776

使用synchronized获取互斥锁的几点说明

转载请注明出处:http://blog.csdn.net/ns_code/article/details/17199201       在并发编程中,多线程同时并发访问的资源叫做临界资源,...
  • HUXU981598436
  • HUXU981598436
  • 2015-02-02 14:53:24
  • 1324

乐观锁与悲观所

悲观锁机制: String hqlStr  =   " from TUser as user where user.name=’Erica’ " ; 2 Query query  =  sess...
  • spjhandsomeman
  • spjhandsomeman
  • 2013-03-11 10:44:26
  • 1372

synchronized的实现用了自旋锁还是互斥锁?

这两个完全不是相同的概念 互斥锁,一般的synchronized,ReentrantLock就是互斥锁,ReentrantReadWriteLock中的写锁也是互斥锁,读锁不是互斥锁。 当线程需要...
  • yingfeng2oo8
  • yingfeng2oo8
  • 2016-01-27 11:30:55
  • 915

Synchronized与Lock之间的哪些事儿

Synchronized、Lock等
  • zyt425916200
  • zyt425916200
  • 2016-09-26 20:01:32
  • 307
    作者
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 115万+
    积分: 1万+
    排名: 964
    博客专栏
    最新评论