java - volatile

volatile主要用来使线程之间数据可见

不同线程操作同一个对象时,会先把对象复制一份给自己的运行内存然后操作完了再放回去。

如果两个线程一起操作对象,两者之间操作的对象其实不是同一个,而是各自拿到的主内存中的复制。

而volatile修饰的对象属性,会保证其可见性,使用这个属性时会同步到主内存,使其他线程知道。

volatile保证了对象属性的一致性,但是不保证原子性。有可能你这边改了一半,另一边已经又变了。。。

 

阿里面试题:

涉及一个容器,线程1往其中添加10个数字,线程二监控线程1,在其添加5个数字时停止。

import java.util.ArrayList;

public class Vol {
    public volatile ArrayList<Integer> arr;

    public Vol(){
        arr = new ArrayList<Integer>();
    }

    public void add(int e){
        arr.add(e);
    }

    public int size(){
        return arr.size();
    }


}

 

main

public class test {
    public static void main(String[] args){
        Vol v =new Vol();

        Thread t1 = new Thread(){

            public int stop = 0;

            @Override
            public void run() {
                for(int i = 1; i <= 10; i++){
                    v.add(i);
                    System.out.println(i + "被加入了");

                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        Thread t2 = new Thread(){
            @Override
            public void run() {
                while(true){
                    if(v.size() == 5){
                        try {
                            System.out.println("线程2停止");
                            break;
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        break;
                    }
                }
            }
        };

        t1.start();
        t2.start();
    }
}

结果:

1被加入了
2被加入了
3被加入了
4被加入了
5被加入了
线程2停止
6被加入了
7被加入了
8被加入了
9被加入了
10被加入了

 

 

 

 

如果改一改,改成当线程1添加5个数字时,线程1停止

随着Thread.stop过期- -现在想从外面停一个线程最好是设置一个开关,外界控制开关,线程内部停止

public class test {

    public static class Thread1 extends Thread{
        public int stop = 0;
    }


    public static void main(String[] args){
        Vol v =new Vol();

        Thread1 t1 = new Thread1(){
            @Override
            public void run() {
                int i = 0;
                while(stop == 0){
                    i++;
                    v.add(i);
                    System.out.println(i + "被加入了");
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        Thread t2 = new Thread(){
            @Override
            public void run() {
                while(true){
                    if(v.size() == 5){
                            try {
                                System.out.println("线程1停止");
                                t1.stop = 1;
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            break;
                    }
                }
            }
        };

        t1.start();
        t2.start();
    }
}

 

 

可以试试把volatile去掉- -会一直走下去,因为t1 和 t2 看到的对象v其实不是同一个,所以等于各自干各自的。

posted @ 2019-11-28 12:06  不咬人的兔子  阅读(219)  评论(0编辑  收藏  举报