zoukankan      html  css  js  c++  java
  • 线程与内存

    在多个线程之间共享了Count类的一个对象,这个对象是被创建在主内存(堆内存)中,每个线程都有自己的工作内存(线程栈),工作内存存储了主内存Count对象的一个副本,当线程操作Count对象时,首先从主内存复制Count对象到工作内存中,然后执行代码count.count(),改变了num值,最后用工作内存Count刷新主内存Count。当一个对象在多个内存中都存在副本时,如果一个内存修改了共享变量,其它线程也应该能够看到被修改后的值,此为可见性。

    每个锁对(JLS中叫monitor)都有两个队列,一个是就绪队列,一个是阻塞队列,就绪队列存储了将要获得锁的线程,阻塞队列存储了被阻塞的线程,当一个线程被唤醒(notify)后,才会进入到就绪队列,等待CPU的调度,反之,当一个线程被wait后,就会进入阻塞队列,等待下一次被唤醒,这个涉及到线程间的通信,当第一个线程执行输出方法时,获得同步锁,执行输出方法,恰好此时第二个线程也要执行输出方法,但发现同步锁没有被释放,第二个线程就会进入就绪队列,等待锁被释放。一个线程执行互斥代码过程如下:
            1. 获得同步锁;
            2. 清空工作内存;
            3. 从主内存拷贝对象副本到工作内存;
            4. 执行代码(计算或者输出等);
            5. 刷新主内存数据;
            6. 释放同步锁。

    在 java 垃圾回收整理一文中,描述了jvm运行时刻内存的分配。其中有一个内存区域是jvm虚拟机栈,每一个线程运行时都有一个线程栈,线程栈保存了线程运行时候变量值信息。当线程访问某一个对象时候值的时候,首先通过对象的引用找到对应在堆内存的变量的值,然后把堆内存变量的具体值load到线程本地内存中,建立一个变量副本,之后线程就不再和对象在堆内存变量值有任何关系,而是直接修改副本变量的值,在修改完之后的某一个时刻(线程退出之前),自动把线程变量副本的值回写到对象在堆中变量。这样在堆中的对象的值就产生变化了。下面一幅图描述这写交互

  • 相关阅读:
    常用算法解析-动态规划
    转载-通过ApplicationContext 去获取所有的Bean
    什么是crud?
    new 关键字 和 newInstance() 方法的 区别
    Java反射简单使用--第一次细致阅读底层代码
    动态创建管理定时任务-已完成
    springboot mail整合freemark实现动态生成模板
    20190930开始记录每天学习状态,更新至20200125结束
    hibernate的对象/关系映射结果为空,exists查不到值的问题-20190823
    转载-Java中LinkedList的一些方法—addFirst addFirst getFirst geLast removeFirst removeLast
  • 原文地址:https://www.cnblogs.com/BlingSun/p/7488497.html
Copyright © 2011-2022 走看看