volatile关键字:

可以用来修饰字段(成员变量),就是告知程序任何对该变量的访问均需要从共享内存中获取,而对它的改变必须同步刷新回共享内存,它能保证所有线程对变量访问的可见性。

synchronized关键字:

可以修饰方法或以同步块的形式来进行使用,它主要确保多个线程在同一时刻,只能有一个线程处于方法或者同步块中,它保证了对变量访问的可见性和排他性。

package com.baidu.nuomi.concurrent;

/**
* Created by sonofelice on 16/6/18.
*/
public class Synchronized {
public static void main(String[] args) {
synchronized (Synchronized.class){ }
}
public static synchronized void m(){}
}

使用javap查看生成的class文件:

在该类的同级目录下执行javap -v Synchronized.class

得到下面的结果:

Classfile /Users/sonofelice/Downloads/zhmmself/target/classes/com/baidu/nuomi/concurrent/Synchronized.class
Last modified 2016-6-18; size 590 bytes
MD5 checksum 64550d9817510bcc5d531e20e814b122
Compiled from "Synchronized.java"
public class com.baidu.nuomi.concurrent.Synchronized
SourceFile: "Synchronized.java"
minor version: 0
major version: 50
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #3.#22 // java/lang/Object."<init>":()V
#2 = Class #23 // com/baidu/nuomi/concurrent/Synchronized
#3 = Class #24 // java/lang/Object
#4 = Utf8 <init>
#5 = Utf8 ()V
#6 = Utf8 Code
#7 = Utf8 LineNumberTable
#8 = Utf8 LocalVariableTable
#9 = Utf8 this
#10 = Utf8 Lcom/baidu/nuomi/concurrent/Synchronized;
#11 = Utf8 main
#12 = Utf8 ([Ljava/lang/String;)V
#13 = Utf8 args
#14 = Utf8 [Ljava/lang/String;
#15 = Utf8 StackMapTable
#16 = Class #14 // "[Ljava/lang/String;"
#17 = Class #24 // java/lang/Object
#18 = Class #25 // java/lang/Throwable
#19 = Utf8 m
#20 = Utf8 SourceFile
#21 = Utf8 Synchronized.java
#22 = NameAndType #4:#5 // "<init>":()V
#23 = Utf8 com/baidu/nuomi/concurrent/Synchronized
#24 = Utf8 java/lang/Object
#25 = Utf8 java/lang/Throwable
{
public com.baidu.nuomi.concurrent.Synchronized();
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 6: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/baidu/nuomi/concurrent/Synchronized; public static void main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=3, args_size=1
0: ldc_w #2 // class com/baidu/nuomi/concurrent/Synchronized
3: dup
4: astore_1
5: monitorenter
6: aload_1
7: monitorexit
8: goto 16
11: astore_2
12: aload_1
13: monitorexit
14: aload_2
15: athrow
16: return
Exception table:
from to target type
6 8 11 any
11 14 11 any
LineNumberTable:
line 8: 0
line 10: 6
line 11: 16
LocalVariableTable:
Start Length Slot Name Signature
0 17 0 args [Ljava/lang/String;
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 11
locals = [ class "[Ljava/lang/String;", class java/lang/Object ]
stack = [ class java/lang/Throwable ]
frame_type = 250 /* chop */
offset_delta = 4 public static synchronized void m();
flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED
Code:
stack=0, locals=0, args_size=0
0: return
LineNumberTable:
line 12: 0
}

分析一下synchronized关键字的实现细节。

上面class信息中,对于同步块的实现使用了

monitorenter  和   monitorexit

指令。而同步方法则是依靠方法修饰符上的

ACC_SYNCHRONIZED

来完成的。

无论哪种方式,其本质是对一个对象的监视器进行获取,而这个获取的过程是排他的,也就是同一时刻只能有一个线程获取到由synchronized所保护对象的监视器。

任意一个对象都拥有自己的监视器,当这个对象由同步块或者这个对象的同步方法调用时,执行方法的线程必须先获取到该对象的监视器才能进入同步块或者同步方法,而没有获取到监视器(执行该方法)的线程将会被阻塞在同步块和同步方法的入口处,进入BLOCKED状态。

volatile关键字和synchronized关键字的更多相关文章

  1. 并发系列2:Java并发的基石,volatile关键字、synchronized关键字、乐观锁CAS操作

    由并发大师Doug Lea操刀的并发包Concurrent是并发编程的重要包,而并发包的基石又是volatile关键字.synchronized关键字.乐观锁CAS操作这些基础.因此了解他们的原理对我 ...

  2. Java:多线程,线程同步,synchronized关键字的用法(同步代码块、非静态同步方法、静态同步方法)

    关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象.本文探讨synchronized关键字. sy ...

  3. 关于synchronized关键字

    1.synchronized关键字的作用域有二种: 1)是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有 ...

  4. synchronized关键字的作用域

    转自:http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html 1.synchronized关键字的作用域有二种: 1)是某个 ...

  5. 云时代架构阅读笔记七——Java多线程中如何使用synchronized关键字

    关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象.本文探讨synchronized关键字. sy ...

  6. 从JAVA看C#中volatile和synchronized关键字的作用

    最近一直在想C#中 volatile关键字到底是用来干什么的?查了很多.NET的文章都是说用volatile修饰的变量可以让多线程同时修改,这是什么鬼... 然后查到了下面这篇JAVA中关于volat ...

  7. volatile与synchronized关键字

    volatile关键字相信了解Java多线程的读者都很清楚它的作用.volatile关键字用于声明简单类型变量,如int.float.boolean等数据类型.如果这些简单数据类型声明为volatil ...

  8. 并发编程之关键字(synchronized、volatile)

    并发编程主要设计两个关键字:一个是synchronized,另一个是volatile.下面主要讲解这两个关键字,并对这两个关机进行比较. synchronized synchronized是通过JMV ...

  9. java中的synchronized关键字

    参考:http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html 多线程并发问题的根因: 在一个对象中有一个变量i=0,有两个线 ...

随机推荐

  1. 测试员浅谈App测试的重点

    近年来,手机app也时持续大热.基于安卓和ios的手机app,更是受到众多投资者的青睐.而手机软件测试行业也是如此. 现在听的最多的是web测试和App测试,但实际上两者本质上没有什么区别,性质都一样 ...

  2. SQL Server 安装报错找不到vc_red.msi

    问题描述: 今天给 WIN 7 SP1 操作系统安装 SQL Server 2014 ,报错找不到vc_red.msi   (图片来源网络,请忽略2012字样..)   问题解决: 1.由于安装程序提 ...

  3. 使用python制作ArcGIS插件(2)代码编写

    使用python制作ArcGIS插件(2)代码编写 by 李远祥 上一章节已经介绍了如何去搭建AddIn的界面,接下来要实现具体的功能,则到了具体的编程环节.由于使用的是python语言进行编程,则开 ...

  4. [Android ADB] An auto-input method for Android and Windows

    The Valentine's Day is coming. Here is an auto-input method and you may use it to send multiple word ...

  5. js-tab选项卡

    说道tab选项卡,顾名思义,就是切换不同内容分类,想必学过前端的都知道,tab有很多方法可以实现,最近刚跟师傅学了一种,感觉很简便,很实用哦.    一.先看一下结果 二.可以根据图来布局,首先上面标 ...

  6. 安卓UDP通信

    功能: 实现了单次一发一收: import java.net.*; import java.io.*; public class udpRecv { /* * 创建UDP传输的接收端 * 1.建立ud ...

  7. 细谈sass和less中的变量及其作用域

    博客原文地址:Claiyre的个人博客 https://claiyre.github.io/ 博客园地址:http://www.cnblogs.com/nuannuan7362/ 如需转载,请在文章开 ...

  8. SQL Server 2008R2 企业版 百度云下载地址

    SQL Server 2008R2 (百度云下载地址:链接: http://pan.baidu.com/s/1mi34II8 密码: yc1w)   ASP.NET MVC4.0+ WebAPI+Ea ...

  9. 【openstack N版】——手把手教你制作生产环境镜像

    一.CentOS7镜像制作 1.1创建CentOS7虚拟机 1.1.1创建虚拟磁盘 #注:尽量将虚拟机创建在控制节点,以便于将镜像上传至glance [root@linux-node1 ~]# qem ...

  10. JavaWeb从0开始学(一)-----搭建第一个Web应用程序与JSP工作原理

    以往学习的时候大多是看完书或者看完视频,动手实践一下就OK了.然而过了一段时间我发现东西都忘差不多了,需要复习才能重新掌握.现在开始学习JavaWeb了,我将在这里记录自己的学习的一点一滴,不仅便于自 ...