美文网首页
关于并发编程中临界资源的问题

关于并发编程中临界资源的问题

作者: 风骚的风 | 来源:发表于2018-06-27 22:21 被阅读0次

临界资源: 指并发环境中多个进程/线程共享的资源.

在并发编程中对临界资源的处理不当, 往往会导致数据不一致的问题. 例如有一份账户数据 account = 6, 它作为一份临界资源被两个线程同时消费.

public class Test {

    private volatile int account = 6;

    public void consume(int amount) {
        // 1. 读取账户
        int currentAccount = account;

        // 2. 消费账户
        if (currentAccount >= amount) {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            currentAccount -= amount;
            System.out.println(String.format("消费了%s元", amount));

            // 3. 更新账户
            account = currentAccount;
        }
    }

    public int getAccount() {
        return account;
    }

    public static void main(String[] args) {
        final Test testObj = new Test();

        Thread threadA = new Thread(() -> testObj.consume(5));
        Thread threadB = new Thread(() -> testObj.consume(6));

        threadA.start();
        threadB.start();

        try {
            threadA.join();
            threadB.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(String.format("账户剩余: %s元", testObj.getAccount()));
    }

}

运行程序后, 你会发现两个线程都消费成功了, 总共消费了 11 元. 究其原因, 是因为一个线程将临界资源置于中间状态后, 另一个线程访问了这个中间状态并基于此中间状态做了进一步的处理. 结合上面的例子, 当线程 A 以的目的account 时, 就已经将 account 置于中间状态了. 直至线程 A 完成对 account 的所有操作前, account 都处于中间状态, 而这个状态对其他线程应该是不可见的. 而上例中的线程 B 因为读取了 account 的中间状态, 并基于这个中间状态做了一系列的处理, 从而导致了数据最终不一致的问题.

总结:

  • 纯粹的读操作并不会将临界资源置于中间状态;
  • 以写为目的的读操作会将临界资源置于中间状态;
  • 处于中间状态的临界资源不支持其他线程以写为目的的读操作, 更不支持操作;
  • 根据实际情况 (可否忍受脏读), 处于中间状态的临界资源可以支持其他线程纯粹的读操作;

正确理解临界资源的中间状态, 对于维护数据的一致性问题非常重要.

相关文章

  • SynChronized

    并发编程对共享资源,临界资源的访问 在并发编程中对临界资源的访问有可能出现并发问题,注意是临界资源,共享资源,普通...

  • 关于并发编程中临界资源的问题

    临界资源: 指并发环境中多个进程/线程共享的资源. 在并发编程中对临界资源的处理不当, 往往会导致数据不一致的问题...

  • synchronized与volatile的区别

    synchronized介绍: 在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访问对象并要求操...

  • 《提升能力,涨薪可待》—Java并发之Synchronized

    Synchronized简介 线程安全是并发编程中的至关重要的,造成线程安全问题的主要原因: 临界资源, 存在共享...

  • Java基础之synchronized关键字

    一、概述 在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访问对象并要求操作相同资源时,分割了原...

  • Java并发编程(7):使用synchronized获取互斥锁的

    在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访问对象并要求操作相同资源时,分割了原子操作就有...

  • java关键字synchronized的使用

    引言 线程安全是并发编程中的重要关注点,而造成线程安全问题的主要原因有两点: 存在共享数据(临界资源); 存在多个...

  • synchronized

    线程安全是并发编程中的重点,造成线程安全问题主要诱因又两点,一是存在共享数据(临界资源),二是存在多条线程共同操作...

  • 25. Mutex

    25. Mutex 临界区 在学习 Mutex 之前,我们需要理解并发编程中临界区(Critical Sectio...

  • synchronized实现原理

    线程安全是并发编程中的重要关注点,应该注意到的是,造成线程安全问题的主要诱因有两点,一是存在共享数据(也称临界资源...

网友评论

      本文标题:关于并发编程中临界资源的问题

      本文链接:https://www.haomeiwen.com/subject/qzwiyftx.html