......
-agentpath:[=]
load native agent library by full pathname
-javaagent:[=]
load Java programming language agent, see java.lang.instrument
-splash:
show splash screen with specified image
See http://www.oracle.com/technetwork/java/javase/documentation/index.html for more details. 0x00007fd34511a20f: mov %rsp,%rdx
0x00007fd34511a212: and $0xfffffffffffffff0,%rsp
0x00007fd34511a216: callq 0x00007fd35a935a40 ; {runtime_call}
0x00007fd34511a21b: hlt
[Deopt Handler Code]
0x00007fd34511a21c: mov $0x7fd34511a21c,%r10 ; {section_word}
0x00007fd34511a226: push %r10
0x00007fd34511a228: jmpq 0x00007fd345047240 ; {runtime_call}
0x00007fd34511a22d: hlt
0x00007fd34511a22e: hlt
0x00007fd34511a22f: hlt
java -XX:+UnlockDiagnosticVMOptions -XX:+TraceClassLoading -XX:+LogCompilation -XX:LogFile=jit.log -XX:-BackgroundCompilation -XX:+PrintAssembly Test
volatile 变量的内存可见性是基于内存屏障(Memory Barrier)实现。
写一段简单的 Java 代码,声明一个 volatile 变量,并赋值。
public class Test {
private volatile int a;
public void update() {
a = 1;
}
public static void main(String[] args) {
Test test = new Test();
test.update();
}
}
......
0x0000000002951563: and $0xffffffffffffff87,%rdi
0x0000000002951567: je 0x00000000029515f8
0x000000000295156d: test $0x7,%rdi
0x0000000002951574: jne 0x00000000029515bd
0x0000000002951576: test $0x300,%rdi
0x000000000295157d: jne 0x000000000295159c
0x000000000295157f: and $0x37f,%rax
0x0000000002951586: mov %rax,%rdi
0x0000000002951589: or %r15,%rdi
0x000000000295158c: lock cmpxchg %rdi,(%rdx) //在 volatile 修饰的共享变量进行写操作的时候会多出 lock 前缀的指令
0x0000000002951591: jne 0x0000000002951a15
0x0000000002951597: jmpq 0x00000000029515f8
0x000000000295159c: mov 0x8(%rdx),%edi
0x000000000295159f: shl $0x3,%rdi
0x00000000029515a3: mov 0xa8(%rdi),%rdi
0x00000000029515aa: or %r15,%rdi
......
2.2.1.1 lock 指令
2.2.1.2 缓存一致性
2.2.2.1 volatile 的 happens-before 关系
//假设线程A执行writer方法,线程B执行reader方法
class VolatileExample {
int a = 0;
volatile boolean flag = false;
public void writer() {
a = 1; // 1 线程A修改共享变量
flag = true; // 2 线程A写volatile变量
}
public void reader() {
if (flag) { // 3 线程B读同一个volatile变量
int i = a; // 4 线程B读共享变量
……
}
}
}
VolatileExample
2.2.2.2 volatile 禁止重排序
volatile 重排序规则表
内存屏障 | 说明 |
---|---|
StoreStore 屏障 | 禁止上面的普通写和下面的 volatile 写重排序。 |
StoreLoad 屏障 | 防止上面的 volatile 写与下面可能有的 volatile 读/写重排序。 |
LoadLoad 屏障 | 禁止下面所有的普通读操作和上面的 volatile 读重排序。 |
LoadStore 屏障 | 禁止下面所有的普通写操作和上面的 volatile 读重排序。 |
volatile 写插入内存屏障
volatile 读插入内存屏障
使用 volatile 必须具备的条件
只有在状态真正独立于程序内其他内容时才能使用 volatile。
模式 #1 状态标志
volatile boolean shutdownRequested;
......
public void shutdown() { shutdownRequested = true; }
public void doWork() {
while (!shutdownRequested) {
// do stuff
}
}
public class BackgroundFloobleLoader {
public volatile Flooble theFlooble;
public void initInBackground() {
// do lots of stuff
theFlooble = new Flooble(); // this is the only write to theFlooble
}
}
public class SomeOtherClass {
public void doWork() {
while (true) {
// do some stuff...
// use the Flooble, but only if it is ready
if (floobleLoader.theFlooble != null)
doSomething(floobleLoader.theFlooble);
}
}
}
public class UserManager {
public volatile String lastUser;
public boolean authenticate(String user, String password) {
boolean valid = passwordIsValid(user, password);
if (valid) {
User u = new User();
activeUsers.add(u);
lastUser = user;
}
return valid;
}
}
@ThreadSafe
public class Person {
private volatile String firstName;
private volatile String lastName;
private volatile int age;
public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
public int getAge() { return age; }
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setAge(int age) {
this.age = age;
}
}
@ThreadSafe
public class CheesyCounter {
// Employs the cheap read-write lock trick
// All mutative operations MUST be done with the 'this' lock held
@GuardedBy("this") private volatile int value;
public int getValue() { return value; }
public synchronized int increment() {
return value++;
}
}
模式 #6 双重检查(double-checked)
class Singleton {
private volatile static Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
syschronized(Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
public class Singleton {
static class SingletonHolder {
static Singleton instance = new Singleton();
}
public static Singleton getInstance(){
return SingletonHolder.instance;
}
}
作者:羽杰
链接:https://www.jianshu.com/p/ccfe24b63d87
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。