JAVA JUC volatile 关键字

1 内存可见性问题

 

 

 

class flagTest implements Runnable{
    private boolean flag = false;

    @Override
    public void run() {

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        flag=true;
        System.out.println("flag="+flag);
    }
    public boolean getFlag(){
        return flag;
    }
}
public class volatileTest {
    public static void main(String[] args) {
        flagTest ft = new flagTest();
        Thread thread = new Thread(ft);
        thread.start();
        while (true){
            if(ft.getFlag()) System.out.println("----------");
        }

    }
View Code

 

如上的程序,主线程会一直在while里面死循环. 这是因为,java程序在主内存里创建了一个flag=false.线程1和主线程读取flag的时候,分别复制了一份.当线程1对flag的值进行修改之后,由于主线程存在flag的副本,且while(true)效率极高,所以没有刷新flag的值,导致主线程陷入死循环.这就是共享变量的内存不可见问题.

要解决这个问题,可以使用synchronized加锁,这样在访问共享变量的时候,就会刷新内存变量.但是弊端是,程序执行效率大幅度下降.

public class volatileTest {
    public static void main(String[] args) {
        flagTest ft = new flagTest();
        Thread thread = new Thread(ft);
        thread.start();
        while (true){
            synchronized (ft){
                if(ft.getFlag()) {
                    System.out.println("----------");
                    break;
                }

            }

        }

    }
main函数修改为这样

使用volatile关键字,可是使得共享变量的内存可见性提高,可以理解为不同的线程直接在主内存里面访问共享变量.

class flagTest implements Runnable{
    private volatile boolean flag = false;

    @Override
    public void run() {

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        flag=true;
        System.out.println("flag="+flag);
    }
    public boolean getFlag(){
        return flag;
    }
}
public class volatileTest {
    public static void main(String[] args) {
        flagTest ft = new flagTest();
        Thread thread = new Thread(ft);
        thread.start();
        while (true){
                if(ft.getFlag()) {
                    System.out.println("----------");
                    break;

            }

        }

    }
View Code
private volatile boolean flag = false;

volatile具有以下特点:

  当线程之间进行数据共享时,使用volatile关键字修饰,可以使得共享变量内存可见,相比与synchronized,它是一种轻量级的线程锁.

  1 不具有互斥性

  2 不能保证变量的原子性.

posted @ 2020-03-11 11:39  超级学渣渣  阅读(115)  评论(0编辑  收藏  举报