java源代码
public class VolatileUsedClass {
private static int sharedVar = 10;
public static void main(String[] args) throws Exception {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
try {
// modify the sharedVar,write first
TimeUnit.MICROSECONDS.sleep(500L);
sharedVar = 20;
System.out.printf("%s modify the shared var to %s ...\n", "thread-1", sharedVar);
} catch (Exception e) {
System.out.println(e);
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
try {
// read the value,read for the last
TimeUnit.MICROSECONDS.sleep(505L);
System.out.printf("%s read the shared var %s \n", "thread-2", sharedVar);
} catch (Exception e) {
System.out.println(e);
}
}
});
thread2.start();
thread1.start();
thread1.join();
thread2.join();
System.out.println("finish the thread task...");
}
}
客户端模式-client
服务端模式,-server
小结
参考JVM Server vs Client Mode:
https://javapapers.com/core-java/jvm-server-vs-client-mode/
说明: 以下运行环境是使用-client模式进行,排除重排序的干扰
Java中的原子性
volatile修饰单个变量的自增减问题
// 部分代码,在上述的写线程进行修改, 前提: volatile修饰变量sharedVar
Thread t1 = new Thread(){
@Override
public void run() {
try {
// modify the sharedVar
TimeUnit.MICROSECONDS.sleep(500L);
sharedVar ++;
System.out.printf("%s modify the shared var with atomic %s ...\n", "thread-1", sharedVar);
} catch (Exception e) {
System.out.println(e);
}
}
};
L3
LINENUMBER 102 L3
BIPUSH 20 // 压入线程的操作数栈
INVOKESTATIC com/xiaokunliu/blogs/thread/volatile2code/VolatileUsedClass.access$002 (I)I //实例化并加载sharedVar并压入操作数栈,说明完成赋值操作
POP // 弹出数据
L4
L3
LINENUMBER 27 L3
INVOKESTATIC com/xiaokunliu/blogs/thread/volatile2code/VolatileUsedClass.access$000 ()I // 实例化并加载sharedVar并压入操作数栈
ICONST_1 // 将常量 1 压入线程操作数栈总
IADD // 执行sharedVar+1
INVOKESTATIC com/xiaokunliu/blogs/thread/volatile2code/VolatileUsedClass.access$002 (I)I // 重新实力化加载sharedVar,说明完成赋值操作
POP
L4
使用volatile小结
参考JDK关于原子性文档:
https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html
感谢花时间阅读,如有用请转发或者点个好看,谢谢!