参考: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. android139 360 黑名单 增删改查-数据库操作

    BlackNumberOpenHelper.java package com.itheima52.mobilesafe.db.dao; import android.content.Context; ...

  2. The internals of Python string interning

    JUNE 28TH, 2014Tweet This article describes how Python string interning works in CPython 2.7.7. A fe ...

  3. 交换a、b

    有两个变量a和b,不使用任何中间变量交换a和b. 方法一: 采用如下方法: a=a+b; b=a-b; a=a-b; 这样做的缺点就是如果a.b都是比较大的数,则a=a+b时就会越界. 而采用: a= ...

  4. 强烈推荐240多个jQuery插件提供下载

    jQuery 是继 prototype 之后又一个优秀的 Javascript 框架.其宗旨是—写更少的代码,做更多的事情.它是轻量级的 js 库(压缩后只有21k) ,这是其它的 js 库所不及 的 ...

  5. Android(java)学习笔记77:网络编程的概述

    计算机网络 是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统. 网络编程 就 ...

  6. Android(java)学习笔记75:匿名内部类的方式实现多线程程序

    二话不说,首先利用代码体现出来,给大家直观的感觉: package cn.itcast_11; /* 4 * 匿名内部类的格式: 5 * new 类名或者接口名() { 6 * 重写方法; 7 * } ...

  7. oracle索引、 管理权限和角色

    索引 1 单列索引create index 索引名 on 表名(列名): 2复合索引在同一张表上可以有多个索引,但是要求列的组合必须不同.create index 索引名 on 表名(列名1, 列名2 ...

  8. javaweb学习总结二(静态导入、自动拆装箱、增强for与可变参数)

    一:静态导入语法:import static 导入类.成员变量|成员方法那么在代码中可以直接使用变量或者方法,而不需要通过类名.来调用 静态导入: import static java.lang.Sy ...

  9. Oracle_11g中解决被锁定的scott用户的方法(转载)

    转自:http://www.2cto.com/database/201402/277206.html Oracle 11g中修改被锁定的用户:scott 在安装完Oracle11g和创建完oracle ...

  10. Android异常:异步任务导致的窗口句柄泄漏问题

    05-05 10:36:41.009: E/WindowManager(4243): Activity com.tao.MyActivity has leaked window com.android ...