数据同步问题探讨

本文通过一个模拟营业厅叫号程序的示例,阐述了在多线程环境下共享资源可能导致的数据不一致问题,包括号码被略过、重复显示和超出最大值等。分析了这些问题产生的原因,涉及线程并发执行和CPU时间片调度。理解这些现象对于确保多线程程序的正确性和数据同步至关重要。
摘要由CSDN通过智能技术生成

一 什么是共享资源

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

二 数据不一致问题的引入

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

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,此时出现了超过最大值的情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值