数据同步问题探讨

x33g5p2x  于2022-03-01 转载在 其他  
字(1.2k)|赞(0)|评价(0)|浏览(225)

一 什么是共享资源

共享资源指的是多个线程同时对同一份资源进行访问(读写操作),被多个线程访问的资源就是共享资源,如何保证多个线程访问到的数据是一致的,则被称为数据同步或者资源同步。

二 数据不一致问题的引入

先看一段代码,它模拟的是营业厅叫号程序。

package concurrent;

public class TicketWindowRunnable implements Runnable {
    private int index = 1;
    private final static int MAX = 500;

    @Override
    public void run() {
        while (index <= MAX) {
            System.out.println(Thread.currentThread() + "的号码是:" + (index++));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        final TicketWindowRunnable task = new TicketWindowRunnable();

        Thread windowThread1 = new Thread(task, "1号窗口");
        Thread windowThread2 = new Thread(task, "2号窗口");
        Thread windowThread3 = new Thread(task, "3号窗口");
        Thread windowThread4 = new Thread(task, "4号窗口");

        windowThread1.start();
        windowThread2.start();
        windowThread3.start();
        windowThread4.start();
    }
}

多次运行上面这段代码,会发现出现了三种问题。

  • 某个号码被略过没有出现
  • 某个号码多次显示
  • 号码超过了最大值500

三 数据不一致问题分析

1 号码被略过

线程的执行是由 CPU 时间片轮询调度的,假设此时线程1和线程2都执行到 index =65,其中线程2将 index 修改为 66 之后未输出之前,CPU 调度器将执行权利交给线程1,线程1将其累加到67,那么66就忽略了。

2 号码重复出现

线程1执行 index+1,然后CPU执行权落入线程2手里,由于线程1并没有给index赋予计算后的结果393,因此线程2执行index+1的结果仍然是393,所以会出现重复号码的情况

3 号码超过了最大值

当 index =499 的时候,线程1和线程都满足条件,线程2短暂停留,线程1强index增加到500,线程2恢复运行后又将500增加到501,此时出现了超过最大值的情况。

相关文章