volatile关键字和synchronized关键字
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关键字的更多相关文章
- 并发系列2:Java并发的基石,volatile关键字、synchronized关键字、乐观锁CAS操作
由并发大师Doug Lea操刀的并发包Concurrent是并发编程的重要包,而并发包的基石又是volatile关键字.synchronized关键字.乐观锁CAS操作这些基础.因此了解他们的原理对我 ...
- Java:多线程,线程同步,synchronized关键字的用法(同步代码块、非静态同步方法、静态同步方法)
关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象.本文探讨synchronized关键字. sy ...
- 关于synchronized关键字
1.synchronized关键字的作用域有二种: 1)是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有 ...
- synchronized关键字的作用域
转自:http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html 1.synchronized关键字的作用域有二种: 1)是某个 ...
- 云时代架构阅读笔记七——Java多线程中如何使用synchronized关键字
关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象.本文探讨synchronized关键字. sy ...
- 从JAVA看C#中volatile和synchronized关键字的作用
最近一直在想C#中 volatile关键字到底是用来干什么的?查了很多.NET的文章都是说用volatile修饰的变量可以让多线程同时修改,这是什么鬼... 然后查到了下面这篇JAVA中关于volat ...
- volatile与synchronized关键字
volatile关键字相信了解Java多线程的读者都很清楚它的作用.volatile关键字用于声明简单类型变量,如int.float.boolean等数据类型.如果这些简单数据类型声明为volatil ...
- 并发编程之关键字(synchronized、volatile)
并发编程主要设计两个关键字:一个是synchronized,另一个是volatile.下面主要讲解这两个关键字,并对这两个关机进行比较. synchronized synchronized是通过JMV ...
- java中的synchronized关键字
参考:http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html 多线程并发问题的根因: 在一个对象中有一个变量i=0,有两个线 ...
随机推荐
- angular表格分页
<!doctype html> <html lang="en" > <head> <meta charset="UTF-8&qu ...
- GitHub客户端发布托管代码
初试GitHub及客户端使用 突然想分享代码,于是记起来曾几何时有人提到过GitHub这个东西,于是便各种百度,注册申请了一个账号,下载了windows客户端,全英文网站就连新手教程也是全英的,现在想 ...
- 使用Navicat Premium 链接本地数据库的方法
在工作中,为了更方便的使用数据库,不免会用到Navicat Premium: 于是在重新安装电脑系统之后,原本想在其中链接一下本地数据库, 只是在链接途中要写的密码一项却不晓得应该写什么,想了很久密码 ...
- CSS实现的几款不错的菜单栏
前言 自从做了智慧城市这个项目之后,我一个做后端的开发者,瞬间转为前端开发,不过我还是很喜欢前端的.前端那些事,其实蛮有意思的,HTML实现的是静态的,使用ajax之后就可以和数据库交互了,加上js和 ...
- ajax提交的javascript代码
var xhr=xhr(); function xhr(){ if(window.XMLHttpRequest){ return window.XMLHttpRequest(); }else if ...
- tomcat启动异常、和web.xml缺少配置异常
错误如下: 14-Feb-2017 10:50:00.665 SEVERE [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.Sta ...
- Linux 6.4 partprobe出现warning问题
今天在给服务器做LVM的时候(服务器的系统是CentOS 6.3),用fdisk分区之后,用w写入分区表的时候,就提示Command (m for help): wThe partition tabl ...
- flex控件总结
Flex基本控件总结 一.flex控件的分类:文本控件(text controls).数据源控件(data provider controls).菜单控件 (menu controls) ...
- DirectX11中Shader的封装
引言 这个寒假学DirectX11的时候用的书是<Introduction to 3D Game Programming with DirectX 11>,里面关于Shader的部分全 ...
- SDOI Day1
好了做了SDOI day1的3道题,来讲下做法及感想吧 T1:排序(暴力,搜索) 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3990 我们可 ...