用Java构建基本的生产消费模型

简介

本篇介绍了用Java构建基本的生产消费模型,采用了多线程以及synchronized 关键字、ReentrantLock等并发工具,介绍了有关竞态条件等知识。

版本一

简单采用两个线程,通过共享的Arraylist实现商品单线的存放和取出

代码部分

运行结果

版本二

尝试多加几个线程,实现多个取出

但是运行结果不尽人意

报错了

这个错误是 ArrayIndexOutOfBoundsException 异常,意味着你尝试访问数组(或类似的数据结构)时使用了一个无效的索引值。这可能表明你的线程之间在并发访问共享数据时出现了问题,导致了数组越界。

这个问题引出了接下来我们要讲的东西

竞态条件

竞态条件(Race Condition)是指在多线程环境中,多个线程并发访问共享资源,最终的结果取决于线程的执行顺序,从而导致无法预测的结果。具体而言,当多个线程同时竞争访问共享资源,并且对资源的操作不是原子性的,就可能发生竞态条件。

典型的竞态条件包括:

  1. 读取-修改-写入操作: 多个线程同时读取某个变量的值,然后进行修改并写回。如果不适当同步,就可能导致其中一个线程的修改被另一个线程覆盖。

  2. 检查-执行操作: 一个线程检查某个条件,然后执行相应的操作。但在执行操作之前,另一个线程可能修改了条件,导致执行的操作不再合适。

竞态条件通常是由于操作的不原子性和缺乏适当的同步机制引起的。为了解决竞态条件,可以使用同步工具,如锁(Locks)、互斥量(Mutexes)或原子操作,确保多个线程在访问共享资源时能够协调并避免冲突。

在 Java 中,使用 synchronized 关键字、ReentrantLock 或其他并发工具来确保线程安全是处理竞态条件的常见方法。此外,还可以使用 volatile 关键字来确保共享变量的可见性。避免竞态条件是多线程编程中的一个重要方面,以确保程序的正确性和可靠性。

以下是两种解决方案

方案一:synchronized 关键字

synchronized关键字使同一个线程在持有锁的情况下可以重复进入由同一把锁保护的同步代码块,避免了导致无法预测的结果。

方案二:ReentrantLock并发工具

ReentrantLock 被用于保护一个临界区,多个线程可以获取锁并执行临界区内的代码。当一个线程获取锁后,其他线程将被阻塞,直到该线程释放锁。

请注意,为了确保在发生异常时也能释放锁,lockunlock 操作应该放在 try...finally 语句块中。这样,无论代码块中发生什么异常,都能确保锁最终被释放,防止死锁的发生。

这样我们就通过以上的知识简单实现了一个简单的生产消费模型。

  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值