美文网首页
多线程(4) — 线程安全问题

多线程(4) — 线程安全问题

作者: 烧杰 | 来源:发表于2018-04-17 22:21 被阅读0次

    多线程为什么会出现数据安全问题,多线程会带来哪些麻烦,应该怎么解决?

    个人理解,对于单核CPU,CPU是在线程间随机快速的切换,快到就相当于同时处理多件事。而开启多个线程后,线程就会执行。一般认为,只有当线程sleep, 或者阻塞时才会停。等着条件到了被再次唤醒。

    出现问题:

    /**
     * Created by qiaorenjie on 2018/4/5.
     */
    public class Test3 {
    
        static int a ;
    
        public static void main(String[] args) {
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 100; i++) {
                        a++;    // 相当于 a= a+1;
                        System.out.println(Thread.currentThread().getName()+"的值: "+a);
                    }
                }
            });
            thread1.start();
    
            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 100; i++) {
                        a++;
                        System.out.println(Thread.currentThread().getName()+"的值: "+a);
                    }
                }
            });
            thread2.start();
            System.out.println("最后的a为: "+a);
        }
    }
    ======console=====
    Thread-0的值: 77
    Thread-0的值: 79
    Thread-1的值: 79
    Thread-0的值: 80
    

    两条线程打印出了相同的数据79,可能是因为:每一个线程都是先去拿a,并加1.再放到一个变量中。这个动作是有可能同时发生,即产生脏读取。 两个人读到同一个值。
    在a++中,相当于a = a+1(此行还是a的值),可能出现a+1;算好值后还没来得及赋值给a,即a还是原来的旧值的时候另一条线程就读了a的值,而此时a的值是旧值,不是应该更改后的新值,此时就发生了脏读,出现上面的问题。

    个人看法:对于共享变量进行原子操作可以不用考虑线程安全,但是一般操作都比较复杂不可能都是原子操作的,所以怎么对同一变量进行安全的线程操作是多线程关注的重点。(本例可以通过将方法抽离出来再对方法加上锁解决)

    相关文章

      网友评论

          本文标题:多线程(4) — 线程安全问题

          本文链接:https://www.haomeiwen.com/subject/nikdhftx.html