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

  • 相关阅读:
    ZOJ 1002 Fire Net
    Uva 12889 One-Two-Three
    URAL 1881 Long problem statement
    URAL 1880 Psych Up's Eigenvalues
    URAL 1877 Bicycle Codes
    URAL 1876 Centipede's Morning
    URAL 1873. GOV Chronicles
    Uva 839 Not so Mobile
    Uva 679 Dropping Balls
    An ac a day,keep wa away
  • 原文地址:https://www.cnblogs.com/clamp7724/p/11949085.html
Copyright © 2011-2022 走看看