zoukankan      html  css  js  c++  java
  • java

    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其实不是同一个,所以等于各自干各自的。

  • 相关阅读:
    Ubuntu查看端口占用情况
    在jupyter中添加新的环境
    C++指针
    C++排序:冒泡排序,简单选择排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序
    查找一:C++静态查找
    C++链式队列
    C++顺序循环队列
    C++链式栈
    C++顺序栈
    C++双向循环链表
  • 原文地址:https://www.cnblogs.com/clamp7724/p/11949085.html
Copyright © 2011-2022 走看看