锁:并发编程中的三个问题(可见性、原子性、有序性)

1、可见性

(1)概念
可见性(Visibility):是指一个线程对共享变量进行修改,另一个线程要立即得到修改后的最新值。

(2)代码演示

public class Test {
        // 多个线程都会访问的数据,我们称为线程的共享数据
        private static boolean run = true;
        public static void main(String[] args) throws InterruptedException {
            Thread t1 = new Thread(() -> {
                while (run) {
                }
            });
            t1.start();
            Thread.sleep(1000);
            Thread t2 = new Thread(() -> {
                run = false;
                System.out.println("时间到,线程2设置为false");
            });
            t2.start();
        }
}

并发编程时,会出现可见性问题,当一个线程对共享变量进行了修改,另外的线程并没有立即看到修改后的最新值。上例中,如果第一个线程检测到的值的改变应该是退出循环的。

2、原子性

(1)概念

原子性(Atomicity):在一次或多次操作中,要么所有的操作都执行并且不会受其他因素干扰而中断,要么所有的操作都不执行。(跟事务的原子性类似)

(2)演示

public class Test {
    /**
     * 案例演示:5个线程各执行1000次 i++;
     */
        private static int number = 0;
        public static void main(String[] args) throws InterruptedException {
            Runnable increment = () -> {
                for (int i = 0; i < 1000; i++) {
                    number++;
                }
            };//number++一千次
            ArrayList<Thread> ts = new ArrayList<>();
            for (int i = 0; i < 5; i++) {
                Thread t = new Thread(increment);
                t.start();
                ts.add(t);
            }//5个线程
            for (Thread t : ts) {
                t.join();
            }//取出5个线程并执行
            System.out.println("number = " + number);
        }
    }

执行的结果是小于5000的

3、有序性

(1)概念

有序性(Ordering):是指程序中代码的执行顺序,Java在编译时和运行时会对代码进行优化,会导致程序最终的执行顺序不一定就是我们编写代码时的顺序。











原文地址:https://www.cnblogs.com/zhai1997/p/13516497.html