大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE稳定放心使用
1、指令重排
JVM为优化执行效率对线程内的执行顺序进行重排,对单线程来说执行指令重排并不会影响程序从上到下执行的代码逻辑。但是在多线程的情况下,则可能会出现问题。
2、指令重排原则
程序顺序原则:一个线程内保证语义的串行性
volatile规则:volatile变量的写,先发生于读
锁规则:解锁(unlock)必然发生在随后的加锁(lock)前
传递性:A先于B,B先于C 那么A必然先于C
线程的start方法先于它的每一个动作
线程的所有操作先于线程的终结(Thread.join())
线程的中断(interrupt())先于被中断线程的代码
对象的构造函数执行结束先于finalize()方法
3、代码示例(实际演示中没有演示出效果)
package com.thread.study;
public class OrderExample {
int a = 0;
boolean flag = false;
public void write(){
a = 1;
flag = true;
}
public void read(){
if(flag){
int i = a + 1;
System.err.println("i="+i+"a="+a+"flag="+flag);
}
}
public static void main(String[] args){
OrderExample order = new OrderExample();
//A线程执行write方法,但是无法保证 a=1执行在前,flag = true执行在后
Thread threadA = new Thread(new Runnable(){
@Override
public void run() {
order.write();
}});
//线程 B执行read方法
Thread threadB = new Thread(new Runnable(){
@Override
public void run() {
order.read();
}});
threadA.start();
threadB.start();
}
}
4、避免指令重排
指令重排是编译器的一种优化手段,但是在多线程中可能会影响到代码逻辑。如何避免指令重排可以通过同步的方式(性能问题)
package com.thread.study;
public class OrderExample {
int a = 0;
boolean flag = false;
public synchronized void write(){
a = 1;
flag = true;
}
public synchronized void read(){
if(flag){
int i = a + 1;
System.err.println("i="+i+"a="+a+"flag="+flag);
}
}
public static void main(String[] args){
OrderExample order = new OrderExample();
//A线程执行write方法,但是无法保证 a=1执行在前,flag = true执行在后
Thread threadA = new Thread(new Runnable(){
@Override
public void run() {
order.write();
}});
//线程 B执行read方法
Thread threadB = new Thread(new Runnable(){
@Override
public void run() {
order.read();
}});
threadA.start();
threadB.start();
}
}
网上看到指令重排会对懒汉-单例模式有影响,后续分析。。。。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/180658.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...