Java编程

图灵java架构第四期

如果要把一个变量从主内存中复制到工作内存中,就需要按顺序地执行read和load操作, 如果把变量从工作内存中同步到主内存中,就需要按顺序地执行store和write操作。但Java内 存模型只要求上述操作必须按顺序执行,而没有保证必须是连续执行。

答案 A出于运行速率的考虑,java编译器会把经常经常访问的变量放到缓存(严格讲应该是工作内存)中,读取变量则从缓存中读。但是在多线程编程中,内存中的值和缓存中的值可能会出现不一致。volatile用于限定变量只能从内存中读取,保证对所有线程而言,值都是一致的。但是volatile不能保证原子性,也就不能保证线程安全。

图灵java架构第四期

用来保证多线程变量间对变量的内存可见性,将最新变量值及时通知给其他线程(让旧值失效)禁止volatile前后的程序指令进行重排序不保证线程安全,不可用于数字的线程安全(比如a++原子性无法保证)使用场景:修饰状态变量,用于线程间访问该变量,保证各线程可以看到最新的内存值单实例对象构造:避免多线程下由于内存不可见导致重复构造对象。

store(存储):作用于工作内存的变量,把工作内存中的一个变量的值传送到主内存中,以便随后的write的操作。

原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。Java内存模型是通过在变量修改后将新值同步会主内存,在变量读取前从主内存刷新变量值这种依赖主内存作为传递媒介的方式来实现可见性,valatile特殊规则保障新值可以立即同步到祝内存中。Synchronized是在对一个变量执行unlock之前,必须把变量同步回主内存中(执行store、write操作)。被final修饰的字段在构造器中一旦初始化完成,并且构造器没有吧this的引用传递出去,那在其他线程中就能看见final字段的值。

)use(使用):作用于工作内存的变量,把工作内存中的一个变量值传递给执行引擎 (6)assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值赋给工作内存的变量。

class HelloThread extends Thread{public volatile boolean running = true;public void run(){while(running){System.out.println(“Hello”);}}}class Main{public static void main(String[] args) throws Exception{HelloThread t = new HelloThread();t.start();Thread.sleep(1000);t.running = false;}}问题:为什么要对线程间共享变量使用关键字volatile声明呢?这涉及到Java的内存模型。在Java虚拟机中,变量的值保存在主内存中,但是当线程访问一个变量的时候,会先获取一个副本,并且保存自己的工作内存中。如果线程修改变量的值,虚拟机会在某个时刻把修改后的值回写到主内存,但是这个时间是不确定的。这会导致如果一个线程更新了某个变量,另一个线程读取的变量还是更新之前的。如主内存中a的值是true。线程1执行时,先读取主内存中a的值(true),将a的值改写为false。但此时仅仅是线程1变量a的副本变为false,主内存中变量a还是true。什么时候虚拟机将线程1修改后的值回写主内存,将a的值更新为false。这个时间是不确定的。这时执行线程2,线程2读取的值可能仍然是true,而不是线程1更新后的false。volatile关键字的目的是告诉虚拟机:

Similar Posts

发表评论

邮箱地址不会被公开。 必填项已用*标注