java-多线程深入(一)JMM

(一)java内存区域概况

jvm运行java程序时把所管理的内存分成几个部分:方法区、java栈、本地方法栈、java堆、pc程序计数器。

class字节码装载解析后,在多线程环境中,方法区和java堆数据共享,每个线程自带pc程序计数器和java栈,栈帧中包含方法的所有状态(局部变量、传参、返回值、运算中间结果等)。对共享数据需要考虑多线程并发问题。

更详细内容可参考《深入理解JVM虚拟机》


(二)计算机系统原型

1.内存和处理器速度不同,缓存的出现,导致数据不同步

多线程都有缓存备份,回写可能会导致数据错误

2.处理器和编译器对代码和指令的优化,导致运算乱序

只要不影响运算结果,处理器可以调整代码执行顺序,多线程操作中会导致数据错误


(三)JMM概况

JMM(java momery model)提供了线程进行通讯时,确保互斥性和可见性。

(1)解决内存可见性问题


共享数据放主内存中,每个线程有自己的工作内存。

线程A读取数据时,先从主内存拷贝数据到工作内存,进行运算后再从工作内存回写到主内存,线程间无法相互访问对方的数据,通过主内存实现通讯。

JMM可以控制指定共享数据实现内存可见性,写入主内存时,同步更新其他线程中的变量值,如volatile变量的使用。

(2)禁止重排序

编译器优化代码,不改变运算结果的情况下,可以实现代码重排序;处理器执行指令,不改变运算结果的情况下,可以实现指令重排序。

JMM可以禁止编译器代码重排序和处理器执行指令重排序(通过加入内层屏蔽)。

多线程并发问题代码剖析

/**
 * 代码重排序demo
 * 
 * @author peter_wang
 * @create-time 2015-1-8 下午3:06:02
 */
public class CodeChangeDemo {

    private static boolean isChange = false;

    private static class ChangeThread
        extends Thread {
        public void run() {
            System.out.println("ChangeThread start"); //1
            isChange = true;                          //2
        };
    };

    private static class GetChangeThread
        extends Thread {
        public void run() {
            System.out.println("GetChangeThread start");
            if (isChange) {                           //3
                isChange = false;
                System.out.println("change success");
            }
            else {
                System.out.println("change no success");
                System.exit(0);
            }
        };
    };

    /**
     * @param args
     */
    public static void main(String[] args) {
        while (true) {
            ChangeThread changeThread = new ChangeThread();
            GetChangeThread getChangeThread = new GetChangeThread();
            changeThread.start();
            getChangeThread.start();
            // 防止线程过多,等执行完上面俩线程再继续
            while (Thread.activeCount() > 1) {

            }
        }
    }

}
运行结果:

ChangeThread start
GetChangeThread start
change success
ChangeThread start
GetChangeThread start
change success
ChangeThread start
GetChangeThread start
change no success
进程退出可能原因:

1.线程ChangeThread中代码顺序调整,1和2调换,执行顺序1-3-2

2.线程ChangeThread执行完,工作内存中的isChange没有回写回主内存,导致3中isChange不是最新值。


参考文献:

1.《深入理解JVM虚拟机》

2.http://ifeve.com/java-memory-model-1/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值