Java 多线程之volatile与synchronized区别

在这里插入图片描述

Volatile

并发编程中volatile和synchronize这两个关键字并不少见,可以理解为volatile就是轻量级synchronized,java多线程支持多个线程同时访问一个成员变量或对象,所以两个关键字都保证了共享变量的可见性,可见性就是当一个线程修改一个共享变量,另一个线程读取到这个共享变量被操作之后的值
随着jdk版本的迭代,synchronized关键字也被优化的很好,并没有所说的那么重

Volatile的实现原理

Java中允许多线程访问共享资源,确保线程安全和一致性,线程通过锁对象来单独获取资源
volatile在某些情况下比锁方便,如果一个变量被声明volatile,那么所有线程看到这个变量的值都是一致的

Volatile关键字的作用

volatile关键字的作用时禁止指令重排序,强制从公共堆栈中取得变量值,而不是从线程私有的数据栈取得变量的值

Synchronized

同步代码块,同步方法在我们的项目中很常见,作用就是用来保证多线程操作共享资源的一致性和原子性
确保共享资源在同一时刻只有一个线程可以访问,其他线程处于阻塞阶段,只有该线程执行完毕或出现异常,才会释放锁对象
其他线程才可以进行下一轮竞争CPU执行权(时间片)

Synchronized的实现原理

synchronized被人一直诟病为重量级锁,相比之下确实没有Lock那么灵活,方便,具体用法可以参考我以上文章Java 多线程之线程安全

!!!注意!!!

  • 使用lock时在finally中必须释放锁,不然容易出现死锁,而使用synchronized时,不必担心,获取锁线程会在执行完同步代码后释放锁,或者JVM会在执行线程异常时释放锁对象
  • 使用lock时线程不会一直等待,而使用synchronized时候,线程A获取对象锁以后,其他线程进入阻塞阶段并一直等待
  • synchronized是隐式锁,在需要同步的资源加入此控制,而Lock锁是显示锁,需要在同步的资源前后加入获取锁和释放锁操作

Synchronized如何实现同步

同步代码块,对象可以为任意类型
也是在括号中写入this,代表当前锁对象就是当前类对象

public class RunnableImpl implements Runnable {
 
    // 定义一个多个线程共享票源
    private int ticket = 30;

    // 创建锁对象
    Object obj = new Object();

    /**
     * 卖票
     */
    @Override
    public void run() {
        while (true) {
            // 创建同步代码块
            synchronized (obj) {
                // 先判断票是否存在
                if (ticket > 0) {
                    // 存在
                    System.out.println(Thread.currentThread().getName() + "--->正在卖票" + ticket + "张票");
                    ticket--;
                }
            }
        }
    }
}

同步方法,方法之上添加synchronized关键字
锁对象即是当前类的实例

public class RunnableImpl implements Runnable {

    // 定义一个多个线程共享票源
    private int ticket = 100;

    /**
     * 卖票
     */
    @Override
    public void run() {
        while (true) {
            updateTicket();
        }
    }
    // 同步方法
    public synchronized void updateTicket() {
        // 先判断票是否存在
        if (ticket > 0) {
            // 存在
            System.out.println(Thread.currentThread().getName() + "--->正在卖票" + ticket + "张票");
            ticket--;
        }
    }
}

Volatile和Synchronized的区别

在这里插入图片描述

  • volatile 不会发生线程阻塞,synchronized会发生线程阻塞
  • volatile 只能修饰变量,synchronized可以修饰同步代码块和方法
  • volatile 不能保证原子性(不能保证线程安全) ,synchronized可以保证原子性
  • volatile 解决的是共享资源在多线程之间的可见性,synchronized 解决的是多线程之间访问共享资源的同步性
发布了24 篇原创文章 · 获赞 33 · 访问量 2391

猜你喜欢

转载自blog.csdn.net/weixin_41241629/article/details/104460593