java中的synchronized关键字
参考:http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html
多线程并发问题的根因:
在一个对象中有一个变量i=0,有两个线程A,B都想对i加1,这个时候便有问题显现出来,关键就是对i加1的这个过程不是原子操作。要想对i进行递增,第一步就是获取i的值,当A获取i的值为0,在A将新的值写入A之前,B也获取了A的值0,然后A写入,i变成1,然后B也写入i,i这个时候依然是1。
当然java的内存模型没有上面这么简单,在Java Memory Model中,Memory分为两类,main memory和working memory,main memory为所有线程共享,working memory中存放的是线程所需要的变量的拷贝,线程要对main memory中的内容进行操作的话,首先需要拷贝到自己的working memory(volatile的变量在被操作的时候不会产生working memory的拷贝,而是直接操作main memory)
针对上面引文中银行取款存款的例子,本来存一百取一百正好抵消,但是由于多线程的之间的肆意抢占,有些取存款的操作被覆盖了,导致结果千奇百怪。
关键点:
synchronized同步加锁的是对象,而不是代码段,这一点一定要理解。
每个对象只有一个锁与之关联。
synchronized作用的域:
(1)关键字synchronized使用在方法之前,类似synchronized aMethod(){},其实是对实例化对象A加锁。
(1.1)可以防止多个线程同时访问这个对象A的synchronized方法,如果有另一个线程要访问该方法的话,需要等待
(1.2)如果对象A有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法
(1.3)当一个线程访问A的一个synchronized(this)同步代码块时,另一个线程仍然可以访问A中的非synchronized(this)同步代码块
(1.4)不同的对象实例的synchronized方法是不相干扰的。例如有该类的另一个对象实例B,B中的synchronized方法现在可以照常访问
(2)关键字synchronized使用方法中的在代码片段中,类似aMethod(){synchronized(this){/*区块*/}},其实也是对实例化对象A加锁,这样做的目的无非是为了减少加锁的范围,提高效率。
(3)在方法中对类加锁。类似aMethod(){synchronized(Foo.class){}},这种情况是对整个class类加锁。它可以对类的所有对象实例起作用。此时该类的所有实例都收到这个锁的节制,只有获取到锁才能够访问
(4)将类的静态成员函数声明为 synchronized。这种锁对类的所有对象实例起作用。与3类似。
其他:
(1)synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法。
(2)还有,博主关于synchronized,用了房间上锁的比喻,非常贴切和易于理解。
java中的synchronized关键字的更多相关文章
- 巨人大哥谈Java中的Synchronized关键字用法
巨人大哥谈Java中的Synchronized关键字用法 认识synchronized 对于写多线程程序的人来说,经常碰到的就是并发问题,对于容易出现并发问题的地方价格synchronized基本上就 ...
- 深入理解java中的synchronized关键字
synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D ...
- Java中的Synchronized关键字用法
认识synchronized 对于写多线程程序的人来说,经常碰到的就是并发问题,对于容易出现并发问题的地方加上synchronized修饰符基本上就搞定 了,如果说不考虑性能问题的话,这一招绝对能应对 ...
- Java中使用同步关键字synchronized需要注意的问题
在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行.synchronized既可以加在一段代码上,也可以加在 ...
- java中的volatile关键字
java中的volatile关键字 一个变量被声明为volatile类型,表示这个变量可能随时被其他线程改变,所以不能把它cache到线程内存(如寄存器)中. 一般情况下volatile不能代替syn ...
- 再议Java中的static关键字
再议Java中的static关键字 java中的static关键字在很久之前的一篇博文中已经讲到过了,感兴趣的朋友可以参考:<Java中的static关键字解析>. 今天我们再来谈一谈st ...
- [多线程] 线程中的synchronized关键字锁
为什么要用锁? 在多线程中,难免会出现在多个线程中对同一个对象的实例变量或者全局静态变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数据其实 ...
- java中的synchronized同步代码块和同步方法的区别
下面这两段代码有什么区别? //下列两个方法有什么区别 public synchronized void method1(){} public void method2(){ synchronized ...
- Java进阶1. Synchronized 关键字
Java进阶1. Synchronized 关键字 20131025 1.关于synchronized的简介: Synchronized 关键字代表对这个方法加锁,相当于不管那一个线程,运行到这个方法 ...
随机推荐
- 阿里技术嘉年华(ADC2013)总结与感悟
上周末刚参加了ADC2013(2013.7.13-14),我报的是TCon测试论坛和UCAN用户体验设计论坛,因为我目前从事的是测试工作,但是还是想往用户体验(主要是用研)方向发展,所以 ...
- 更新mac自带的python
mac lion自带的python是2.7版本的,有点儿低,要使用一些应用的时候还需要3.3以上的,这时可以用以下的方法更新mac自带的python. 先去python的官网下载最新的python,并 ...
- perl 变量详解
http://www.perlmonks.org/?node_id=933450 use strict; use Devel::Peek; my $a; Dump($a); $a=4; Dump($a ...
- Shell脚本调试工具set
可以使用set命令的x选项,显示所有命令执行及变量值的变化过程等. 具体使用方法:首先使用set -x开启调试模式,最后使用命令set +x关闭调试模式. 一个简单示例演示如何使用set命令进行脚本调 ...
- 更改gps.conf来加快GPS搜星速度
国内NTP ServerNTP全称是Network Time Protocol,是用来让计算机之间实现时间同步的协议,而发布这种校对时间的服务器,就是NTP Server!一般来说客户端与服务器之间的 ...
- 实现struts2框架
Struts最早是作为Apache Jakarta项目的组成部分,项目的创立者希望通过对该项目的研究,改进和提高JavaServer Pages .Servlet.标签库以及面向对象的技术水准.最初的 ...
- Linux 通过 load average 判断服务器负载情况
Linux中load average判断服务器负载情况 转载文章 http://www.111cn.net/sys/linux/56003.htm 写的比较详细,推荐看看.
- CentOS(七)--Linux文件类型及目录配置
这篇随笔将会对Linux系统的文件类型以及Linux的目录结构进行详细补充(linux中目录管理和权限非常重要,特别是在linux安装数据库类软件). 一.Linux更改文件权限的两种方式 在之前的一 ...
- [转]在 Windows Server 2012 上安装 IIS 8
本文转自:http://www.starland.net.cn/blog/view/158/1.aspx 本文译自:http://learn.iis.net/page.aspx/1088/instal ...
- [改善Java代码]强制声明泛型的实际类型
Arrays工具类有一个方法asList可以把一个变长参数或数组变成列表,但是它有一个缺点:它所生成的List长度是不可改变的,而这在我们的项目开发中很不方便. import java.util.Ar ...