参考: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关键字的更多相关文章

  1. 巨人大哥谈Java中的Synchronized关键字用法

    巨人大哥谈Java中的Synchronized关键字用法 认识synchronized 对于写多线程程序的人来说,经常碰到的就是并发问题,对于容易出现并发问题的地方价格synchronized基本上就 ...

  2. 深入理解java中的synchronized关键字

    synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D ...

  3. Java中的Synchronized关键字用法

    认识synchronized 对于写多线程程序的人来说,经常碰到的就是并发问题,对于容易出现并发问题的地方加上synchronized修饰符基本上就搞定 了,如果说不考虑性能问题的话,这一招绝对能应对 ...

  4. Java中使用同步关键字synchronized需要注意的问题

    在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行.synchronized既可以加在一段代码上,也可以加在 ...

  5. java中的volatile关键字

    java中的volatile关键字 一个变量被声明为volatile类型,表示这个变量可能随时被其他线程改变,所以不能把它cache到线程内存(如寄存器)中. 一般情况下volatile不能代替syn ...

  6. 再议Java中的static关键字

    再议Java中的static关键字 java中的static关键字在很久之前的一篇博文中已经讲到过了,感兴趣的朋友可以参考:<Java中的static关键字解析>. 今天我们再来谈一谈st ...

  7. [多线程] 线程中的synchronized关键字锁

    为什么要用锁? 在多线程中,难免会出现在多个线程中对同一个对象的实例变量或者全局静态变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数据其实 ...

  8. java中的synchronized同步代码块和同步方法的区别

    下面这两段代码有什么区别? //下列两个方法有什么区别 public synchronized void method1(){} public void method2(){ synchronized ...

  9. Java进阶1. Synchronized 关键字

    Java进阶1. Synchronized 关键字 20131025 1.关于synchronized的简介: Synchronized 关键字代表对这个方法加锁,相当于不管那一个线程,运行到这个方法 ...

随机推荐

  1. 赵雅智_Fragment生命周期

    官网帮助文档链接:  http://developer.android.com/guide/components/fragments.html 主要看两张图.和跑代码 一,Fragment的生命周 w ...

  2. MySQL Router 测试使用 转

    MySQL Router 测试使用 . 特性 MySQL Router 并没有包括一些特别新的特性, 总体上看中规中矩, 不过 first-available 和插件两个特性挺有意思, 后续会进行讲解 ...

  3. OpenVPN中的几个和连接相关的Timer解析

    在OpenVPN中存在几个计时器,这些计时器限制着OpenVPN的一些特定行为的最长持续时间,如果设置不好,就会带来莫名其妙的断线问题,然而如何设置这些计数器也没有一个通用的方案,特定情况下不能太大也 ...

  4. 使用mii-tool设置网卡速率

    转载:http://washion2008.blog.163.com/blog/static/144227201001711537158/ 在ubuntu中,mii-tool 是属于net-tools ...

  5. hibernate 入门案例

    1,创建工程,导入jar ojdbc14.jar 数据库驱动包,我用的是oracle数据库,根据实际的数据库选择驱动包 创建java类,并利用bibernate插件完成orm映射,创建hbm.xml ...

  6. JavaScript版几种常见排序算法

    今天发现一篇文章讲“JavaScript版几种常见排序算法”,看着不错,推荐一下原文:http://www.w3cfuns.com/blog-5456021-5404137.html 算法描述: * ...

  7. Java之MySql数据库链接

    一 下载MySql驱动包,下载途径很多,随便Google或度娘一下就有,我下载的是mysql-connector-java-5.1.26版本,下载后把它解压到指定路径 二 在Eclipse中新建项目T ...

  8. hdu 1423 最长公共递增子序列

    这题一开始把我给坑了,我还没知道LCIS的算法,然后就慢慢搞吧,幸运的是还真写出来了,只不过麻烦了一点. 我是将该题转换为多条线段相交,然后找出最多多少条不相交,并且其数值死递增的. 代码如下: #i ...

  9. hdu 4628 动态规划

    思路:首先就是状态压缩,然后判断哪些状态是回文串.最后就是动态方程:dp[i]=min(dp[i],dp[j]+1).这个方程得前提条件是状态(j-i)为回文串. #include<iostre ...

  10. CF 13E. Holes 分块数组

    题目:点这 跟这题BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊  一模一样 分析: 分块数组入门题. 具体的可以学习这篇博文以及做国家集训队2008 - 苏煜<对块状链表的一 ...