自学-volatile关键字-02

来源:互联网 发布:linux vi编辑器c 编辑:程序博客网 时间:2024/06/11 01:12

首先我们在学习JUC之前呢,我们先来学习一个小的DEMO,然后通过分析,来看下内存的可见性问题。


package com.yiyi.juc;public class JUCTest01 {public static void main(String[] args) {ThreadTest threadTest = new ThreadTest();new Thread(threadTest).start();//若是true则打印下面的“------------------”while(true){if(threadTest.isFlag()){System.out.println("------------------");break;}}}}class ThreadTest implements Runnable{//俩个线程共享的数据private boolean flag=false;@Overridepublic void run() {try {Thread.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}flag=true;System.out.println("flag1--->"+flag);}public boolean isFlag() {return flag;}public void setFlag(boolean flag) {this.flag = flag;}}
先进行执行,看下结果:


只是打印了run()方法中的语句,但是为什么在执行while(true){.......}不执行了呢?

原因:

首先我们必须得理解上述DEMO:首先有2个线程:main线程和线程1.

如图来进行解释:



因为线程1和main线程俩者之间执行的内存是不可见的,所以会导致出现这种问题,那么我们该怎么去解决这种问题呢?有2种方法:

1. synchronized进行同步。

while(true){synchronized (threadTest) {if(threadTest.isFlag()){System.out.println("------------------");break;}}}

2.使用关键字:volatile修饰。

//俩个线程共享的数据private volatile boolean flag=false;


打印结果:


俩者的区别:

1.volatile轻量级,只能修饰变量。

   synchronized重量级,还可修饰方法。

2.volatile只能保证数据的可见性,不能用来同步,因为多个线程并发访问volatile修饰的变量不会阻塞。

synchronized不仅保证可见性,而且还保证原子性,只有获得了锁的线程才能执行,从而保证所有语句都全部执行。多个线程争抢synchronized锁对象时,会出现阻塞。

其他的区别我们在慢慢发现吧!

注意:若哪里分析的不对请指出!谢谢!


0 0
原创粉丝点击