Java教程

并发编程

本文主要是介绍并发编程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

并发编程三大特性:可见性、有序性、原子性

一、可见性

1、volatile保证可见性

public class MyVolatile {
    private static /*volatile*/ boolean running = true;

    private static void m(){
        System.out.println("start");
        while (running){

        }
        System.out.println("end");
    }

    public static void main(String[] args) throws InterruptedException {
        new Thread(MyVolatile::m,t1).start();

        Thread.sleep(10000);

        running = false;
    }
}  这段代码在打印出start后永远也不会打印end

因为running变量是放在内存中,每一个线程都会读这个变量并且把这个变量放到线程本地的缓存中

上面代码是修改了主线程缓存到本地的变量,但是此次修改t1线程依旧读的是t1本地的变量,所以t1调用的m方法读到的变量永远为true

解决方法:将变量修改为volatile

原理:用volatile修饰的变量保证了对每个线程读取到的数据同步

2、synchronized也可以保证可见性,但是不能保证有序性

二、有序性

1、程序在运行过程中如果上下两行代码之间没有依赖关系,可能会造成执行顺序不一致的情况

public class 可见性有序性 {
    private static boolean ready = false;
    private static int number;
    
    private static class ReaderThread extends Thread {
        @Override
        public void run() {
            while (!ready) {
                Thread.yield();
            }
            System.out.println(number);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t = new ReaderThread();
        t.start();
        number = 42;
        ready = true;
        t.join();
    }
}

如上代码有两个问题:有序性和可见性

  可见性:主线程修改number变量为42后,ReaderThread线程读取自身线程缓存值依然为初始值0

  有序性:number=42与ready=true这两行代码之间没有依赖关系,可能会先执行ready=true后执行number=42,这样就有可能导致输出结果为0

三、原子性

1、原子操作:线程操作时不能被其他线程打断,不能并发执行

2、如何保证原子性操作:synchronized

3、上锁本质:把并发操作编程了序列化操作(按照顺序执行)

4、悲观锁:悲观的认为操作会被其他线程打断。

5、乐观锁:乐观的认为操作不会被其他线程打断。

   CAS:初始值为0,要将0变为1,在修改为1后去比较之前要修改的值是否还是0。如果是0则修改,否则重复执行cas操作

      ABA问题:将0变为1后,拿着0回去比较修改值是否为0,发现还是0,但是这个0可能是别人把0变为8之后又变为0的情况。

      解决ABA问题:加版本号

   CAS是原子性的,在cpu底层就支持。入参有三个(修改的值,判断与未修改前的值是否一致,修改后的值)

6、乐观锁与悲观锁谁的效率更高

  悲观锁:a线程抢到锁,之后会维持一个等待队列,队列中都是等待锁释放的线程。这些等待的线程不消耗cpu

  乐观锁:a线程抢到锁,其他线程会不断循环去查看锁是否被释放。自旋现象会消耗cpu资源

综上所述,当a线程执行时间较长时,使用悲观锁,让其他线程到等待队列中等待。当a执行时间很短时,使用乐观锁

  

 

这篇关于并发编程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!