如何实现有界缓冲区的同步检查以避免竞争条件?

错误404

在处理经典的多个消费者/生产者问题时,我遇到了一个问题,即如何避免在插入圆形缓冲区或从圆形缓冲区中移出时出现竞争状况。提前感谢您的帮助!

用于示例的循环缓冲区的示例代码。与我的实现类似(注意:我不能使用集合类型,只能使用数组):

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class BoundedBuffer {
    private final String[] buffer;
    private final int capacity;

    private int front;
    private int rear;
    private int count;

    private final Lock lock = new ReentrantLock();

    private final Condition notFull = lock.newCondition();
    private final Condition notEmpty = lock.newCondition();

    public BoundedBuffer(int capacity) {
        super();

        this.capacity = capacity;

        buffer = new String[capacity];
    }

    public void deposit(String data) throws InterruptedException {
        lock.lock();

        try {
            while (count == capacity) {
                notFull.await();
            }

            buffer[rear] = data;
            rear = (rear + 1) % capacity;
            count++;

            notEmpty.signal();
        } finally {
            lock.unlock();
        }
    }

    public String fetch() throws InterruptedException {
        lock.lock();

        try {
            while (count == 0) {
                notEmpty.await();
            }

            String result = buffer[front];
            front = (front + 1) % capacity;
            count--;

            notFull.signal();

            return result;
        } finally {
            lock.unlock();
        }
    }
}

我需要知道的是如何实现一种检查缓冲区是否为空/空的方法?此方法需要包含在此BoundedBuffer中,并且在继续进行/调用插入/编写方法之前,必须从另一个类(生产者/消费者)中调用此方法。

Producer类中方法的伪代码。

    if (!bufferFull) {
        buffer.addelement;
    }

    else {
        thread.sleep(5)
        threadHasSleptFor++;
    }

我正在使用线程,并且有多个生产者/消费者(在这种情况下为2个生产者/消费者,但我可能需要更多)。我需要它,以便如果缓冲区已满,线程必须等待直到可以插入为止,并且需要存储其等待时间以用于输出(非调试,这是核心功能的一部分)。我遇到的问题是这样的:

  1. 线程1生产者检查是否为bufferfull条件,这是错误的。
  2. 计划程序中途切换到线程2。
  3. 线程2还检查bufferfull条件,这是错误的。
  4. 线程2继续插入。
  5. 计划程序切换回线程1。
  6. 现在,线程1已进入插入行,因为它已被检查,但是线程2击败了它。
  7. 布姆

Java方面有些新知识,但据我了解,这是“检查时间/使用时间”竞争条件问题。

有人可以建议如何安全地实现它,以及如何循环代码,以便threadHasSleptFor变量在每次失败时都保持递增状态(提供方法会很棒)。我想要它,以便只有请求检查的线程可以开始插入项目;第二个生产者必须等待锁。

谢谢。

飞行

根据定义,如果没有更高级别的锁定,这是不可能做到的。

从线程的角度来看,您必须保证检查缓冲区是否已满以及以下插入是否是原子的,这意味着您必须获取一些公共锁才能这样做。这个普遍的问题的确称为检查时间到使用时间,并导致许多有趣的比赛条件。

这些问题的解决方案是不检查是否可以先执行某项操作,然后再执行该操作,而只是尝试执行该操作并处理错误情况。因此,如果您不想在缓冲区的操作已满时阻塞,只需实现一个tryDeposit方法,如果该方法无法存储值,则该方法将引发异常,或者返回布尔值成功值。

尽管在您的情况下,如果您必须存储将值压入堆栈之前所需的时间,我不明白为什么会这样简单:

long start = System.nanotime();
queue.deposit();
long end = System.nanotime();

也不会成功。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Erlang有界缓冲区测试程序

来自分类Dev

有界缓冲区,互斥与空的顺序。首先

来自分类Dev

无锁有界MPMC环形缓冲区故障

来自分类Dev

使用Java库信号量的有界缓冲区

来自分类Dev

如何正确使用new和delete(以避免缓冲区溢出问题)

来自分类Dev

如何避免返回参数中的(有界)通配符

来自分类Dev

为什么我得到不同的输出?我正在使用有界缓冲区、pthreads 和信号量使用 C++ 进行编码

来自分类Dev

如何实现缓冲区溢出

来自分类Dev

假脱机XML结果时如何查询特定数量的行以避免缓冲区溢出

来自分类Dev

Django 1.6交易以避免竞争条件

来自分类Dev

在 Flex 中使用多个缓冲区时,如何避免令牌在缓冲区之间拆分

来自分类Dev

如何将现有缓冲区附加到Realgud调试器?

来自分类Dev

如何在vim的新选项卡中编辑现有缓冲区?

来自分类Dev

如何在vim中垂直拆分现有缓冲区?

来自分类Dev

如何使用javascript中的现有结构缓冲区构建flatbuffers消息

来自分类Dev

如何同步多线程OpenGL缓冲区访问?

来自分类Dev

缓冲区溢出实现

来自分类Dev

VST插件:如何实现“超前”缓冲区?

来自分类Dev

环形缓冲区的有效边界检查

来自分类Dev

如何检查缓冲区是否为空?

来自分类Dev

如何检查Vim缓冲区是否可修改?

来自分类Dev

如何检查输入缓冲区是否为空?

来自分类Dev

nodejs缓冲区是异步还是同步?

来自分类Dev

nodejs缓冲区是异步还是同步?

来自分类Dev

在C#中同步缓冲区

来自分类Dev

vim quickfix避免更改缓冲区

来自分类Dev

如何控制有界源分割?

来自分类Dev

在三层体系结构中使用实体框架实现有界上下文

来自分类Dev

GPflow 2.0中使用Tensorflow双射链实现有界超参数优化

Related 相关文章

  1. 1

    Erlang有界缓冲区测试程序

  2. 2

    有界缓冲区,互斥与空的顺序。首先

  3. 3

    无锁有界MPMC环形缓冲区故障

  4. 4

    使用Java库信号量的有界缓冲区

  5. 5

    如何正确使用new和delete(以避免缓冲区溢出问题)

  6. 6

    如何避免返回参数中的(有界)通配符

  7. 7

    为什么我得到不同的输出?我正在使用有界缓冲区、pthreads 和信号量使用 C++ 进行编码

  8. 8

    如何实现缓冲区溢出

  9. 9

    假脱机XML结果时如何查询特定数量的行以避免缓冲区溢出

  10. 10

    Django 1.6交易以避免竞争条件

  11. 11

    在 Flex 中使用多个缓冲区时,如何避免令牌在缓冲区之间拆分

  12. 12

    如何将现有缓冲区附加到Realgud调试器?

  13. 13

    如何在vim的新选项卡中编辑现有缓冲区?

  14. 14

    如何在vim中垂直拆分现有缓冲区?

  15. 15

    如何使用javascript中的现有结构缓冲区构建flatbuffers消息

  16. 16

    如何同步多线程OpenGL缓冲区访问?

  17. 17

    缓冲区溢出实现

  18. 18

    VST插件:如何实现“超前”缓冲区?

  19. 19

    环形缓冲区的有效边界检查

  20. 20

    如何检查缓冲区是否为空?

  21. 21

    如何检查Vim缓冲区是否可修改?

  22. 22

    如何检查输入缓冲区是否为空?

  23. 23

    nodejs缓冲区是异步还是同步?

  24. 24

    nodejs缓冲区是异步还是同步?

  25. 25

    在C#中同步缓冲区

  26. 26

    vim quickfix避免更改缓冲区

  27. 27

    如何控制有界源分割?

  28. 28

    在三层体系结构中使用实体框架实现有界上下文

  29. 29

    GPflow 2.0中使用Tensorflow双射链实现有界超参数优化

热门标签

归档