2、学习并发的特性

原子性

原子性是指一个操作或一组操作在执行过程中不可被中断,一个操作或者一组操作要么全部成功执行

问题代码

public class Test
{
    static int count = 0;
    public static void main( String[] args ) throws InterruptedException {

        for (int i = 0; i < 11; i++) {
            new Thread(()->{
                for (int j = 0; j < 1000; j++) {
                    increment();
                }
            }).start();
        }
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                for (int j = 0; j < 1000; j++) {
                    decrement();
                }
            }).start();
        }

        Thread.sleep( 500);
        System.out.println(count);
    }

    private static void increment( ){
        count++;
    }

    public static void decrement( ){
        count--;
    }

}

实际输出值和期望值不一致

保障原子性-synchronized

public class Test
{

    static final Object lock = new Object();
    static int count = 0;
    public static void main( String[] args ) throws InterruptedException {

        for (int i = 0; i < 11; i++) {
            new Thread(()->{
                for (int j = 0; j < 1000; j++) {
                    increment();
                }
            }).start();
        }
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                for (int j = 0; j < 1000; j++) {
                    decrement();
                }
            }).start();
        }

        Thread.sleep( 500);
        System.out.println(count);
        Thread.sleep( 500);
        System.out.println(count);
    }

    private static void increment( ){
        synchronized (lock) {
            count++;
        }
    }

    public static void decrement( ){
        synchronized (lock) {
            count--;
        }
    }

}

保障原子性-Atomic类

public class Test
{

    static AtomicInteger count = new AtomicInteger(0);
    public static void main( String[] args ) throws InterruptedException {

        for (int i = 0; i < 11; i++) {
            new Thread(()->{
                for (int j = 0; j < 1000; j++) {
                    increment();
                }
            }).start();
        }
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                for (int j = 0; j < 1000; j++) {
                    decrement();
                }
            }).start();
        }

        Thread.sleep( 500);
        System.out.println(count);
        Thread.sleep( 500);
        System.out.println(count);
    }

    private static void increment( ){
        count.incrementAndGet();
    }

    public static void decrement( ){
        count.decrementAndGet();
    }

}

 ABA问题

public class Test
{

    static AtomicReference<Integer> count = new AtomicReference<>(0);
    public static void main( String[] args ) throws InterruptedException {

        for (int i = 0; i < 11; i++) {
            new Thread(()->{
                for (int j = 0; j < 1000; j++) {
                    increment();
                }
            }).start();
        }
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                for (int j = 0; j < 1000; j++) {
                    decrement();
                }
            }).start();
        }

        Thread.sleep( 500);
        System.out.println(count);
        Thread.sleep( 500);
        System.out.println(count);
    }

    private static void increment( ){
        count.updateAndGet(v -> v + 1);
    }

    public static void decrement( ){
        count.updateAndGet(v -> v - 1);
    }

}

保障原子性-ReentrantLock 

public class Test
{

    static Integer count = 0;
    static final ReentrantLock lock = new ReentrantLock();
    public static void main( String[] args ) throws InterruptedException {

        for (int i = 0; i < 11; i++) {
            new Thread(()->{
                for (int j = 0; j < 1000; j++) {
                    increment();
                }
            }).start();
        }
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                for (int j = 0; j < 1000; j++) {
                    decrement();
                }
            }).start();
        }

        Thread.sleep( 500);
        System.out.println(count);
        Thread.sleep( 500);
        System.out.println(count);
    }

    private static void increment( ){
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }

    public static void decrement( ){
        lock.lock();
        try {
            count--;
        } finally {
            lock.unlock();
        }
    }

}

可见性

一个线程对另一个线程修改的变量是否能够看到

public class Test {

    static boolean flag = true;

    public static void main(String[] args) throws InterruptedException {

        new Thread(()->{
            while (flag){
//                System.out.println("1111");
            }
        }).start();
        new Thread(()->{
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            flag = false;
        }).start();
        Thread.sleep(200);
        System.out.println("标记状态"+flag);
    }
}

flag已经修改,但是程序不会结束

保障可见性-volatile

对公共变量加上volatile关键字

public class Test {

    static volatile boolean flag = true;

    public static void main(String[] args) throws InterruptedException {

        new Thread(()->{
            while (flag){

            }
        }).start();
        new Thread(()->{
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            flag = false;
        }).start();
        Thread.sleep(200);
        System.out.println("标记状态"+flag);
    }
}

 保障可见性-synchronized

public class Test {

    static boolean flag = true;
    static Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            while (flag){
                synchronized(lock) {

                }
            }
        }).start();
        new Thread(()->{
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            synchronized(lock) { // 对 flag 加锁
                flag = false;
            }
        }).start();
        Thread.sleep(200);
        System.out.println("标记状态"+flag);
    }
}

如果synchronized在循环外出现锁被占用的情况,线程2修改标记无法执行

public class Test {

    static boolean flag = true;
    static Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {

        new Thread(()->{
            synchronized(lock) {
                while (flag){

                }
            }
        }).start();
        new Thread(()->{
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            synchronized(lock) { // 对 flag 加锁
                flag = false;
            }
        }).start();
        Thread.sleep(500);
        System.out.println("标记状态"+flag);
    }
}

  保障可见性-Lock

public class Test {

    static boolean flag = true;
    private static Lock lock = new ReentrantLock();

    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            while (flag){
                lock.lock();
                try{

                }finally {
                    lock.unlock();
                }
            }
        }).start();
        new Thread(()->{
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            lock.lock();
            try{
                flag = false;
            }finally {
                lock.unlock();
            }
        }).start();
        Thread.sleep(200);
        System.out.println("标记状态"+flag);
    }
}

有序性

public class Test {

    static int count = 0;
    static boolean flag = false;

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            count = 0;
            flag = false;
            Thread t1 = new Thread(() -> {
                if (flag) {
                    count += count;
                } else {
                    count = 1;
                }
            });
            Thread t2 = new Thread(() -> {
                count = count+5 ;
                flag = true;
            });

            t1.start();
            t2.start();
            t1.join();
            t2.join();
            //1、如果先执行t1,flag = false count = 1
            //   再执行 count = 1+5 = 6,将flag赋值为true

            //2、如果先执行t2,count = 0+5,将true转变成true
            // 再执行t2,count 就变成了10
            if (count == 1) {
                System.out.println("第" + i + "次循环   count = " + count + "   flag=" + flag);
            }
        }
    }
}

 执行出来会出现先执行了线程1的count=1,再执行flag=true

保障有序性-volatile+Lock

public class Test {

    static volatile int count = 0;
    static volatile boolean flag = false;
    private static final ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            count = 0;
            flag = false;
            Thread t1 = new Thread(() -> {
                lock.lock();
                try {
                    if (flag) {
                        count += count;
                    } else {
                        count = 1;
                    }
                } finally {
                    lock.unlock();
                }
            });
            Thread t2 = new Thread(() -> {
                lock.lock();
                try {
                    count = count+5 ;
                    flag = true;
                } finally {
                    lock.unlock();
                }
            });

            t1.start();
            t2.start();
            t1.join();
            t2.join();
            //1、如果先执行t1,flag = false count = 1
            //   再执行 count = 1+5 = 6,将flag赋值为true

            //2、如果先执行t2,count = 0+5,将true转变成true
            // 再执行t2,count 就变成了10
            if (count == 1) {
                System.out.println("第" + i + "次循环   count = " + count + "   flag=" + flag);
            }
        }
        System.out.println("执行结束");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值