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

2018-04-17  本文已影响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的值是旧值,不是应该更改后的新值,此时就发生了脏读,出现上面的问题。

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

上一篇下一篇

猜你喜欢

热点阅读