当前位置: 首页 > 知识库问答 >
问题:

多线程生产者/消费者同步问题

莘欣怿
2023-03-14

我有两个线程的问题,似乎没有正确同步。我基本上有一个布尔值名为“已占用”。当没有线程启动时,它被设置为false。但是当一个线程启动时,线程集被占用是真的,我有一个类,它有线程(run),它们调用下面的函数。

这是一个模拟银行的示例,它接收一个金额(初始余额),然后随机执行取款和存款。我的教授提到了一些关于从取款线程到存款线程的信号?这是怎么回事?在提取线程中,它应该运行到余额为2低,并等待存款线程。我该怎么做?

   package bank;

import java.util.Random;
import bank.Bank;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.Condition;

/**
 *
 * @author KJ4CC
 */
public class Action {

    private Lock accessLock = new ReentrantLock();
    private Condition cond = accessLock.newCondition();
    //private Condition withdraw  = accessLock.newCondition();


    Random rand = new Random();
    Object lock = new Object();
    Bank getBalance = new Bank();

    public void widthdrawl(int threadNum) throws InterruptedException {
        int amount = rand.nextInt(50);
            accessLock.lock();

            if (getBalance.getbalance() > amount) {

                getBalance.setBalance(getBalance.getbalance() - amount);

                System.out.println("\t\t\tThread " + threadNum + " withdrawls " + amount + "\t Balance is " + getBalance.getbalance());

            } else {

                System.out.println("\t\t\tThread " + threadNum + " Failed to withdrawl " + amount + "\t Balance is " + getBalance.getbalance());
                cond.await();

            }


            accessLock.unlock();
            Thread.sleep(rand.nextInt(5));

    }

    public void deposit(int threadNum) throws InterruptedException {
        int amount = rand.nextInt(200);
        accessLock.lock();


            getBalance.setBalance(getBalance.getbalance() + amount);
            System.out.println("Thread " + threadNum + " Deposits " + amount + "\t\t\t\t Balance is " + getBalance.getbalance());
            Thread.sleep(rand.nextInt(100));

            cond.signal();
            accessLock.unlock();


    }
}

共有2个答案

鲁成天
2023-03-14

首先,你必须标记你的变量易失性。如果没有这个关键字,改变一个线程中的变量值在另一个线程中是不可见的。

第二,尝试为bank实体实现外部同步策略。这样的想法基本上是不好的:如果有人使用相同的bank而没有正确同步,它将打破内部bank状态。最好实现内部同步策略,允许银行自行保护自己的状态。

例如Bank类的API可能是这样的

class Bank {
   double synchronize getBalance() { ... }
   void synchronize deposit(double amount) { ... }
   void synchronize widthdrawl(double amount) throw BankException { ... }
}

通过此设计,内部银行状态始终保持一致,任何银行用户将等待自动完成当前银行操作。

邓英卓
2023-03-14

您的锁定条件使用错误。您正在调用lock()而没有在任何地方调用unlock(),您正在调用signal()而没有任何人调用wait()

有关与您的问题密切相关的示例,请参阅文档。

 类似资料:
  • 所谓的生产者消费者模型就是 某个模块(函数)负责生产数据,这些数据由另一个模块来负责处理 一般生产者消费者模型包含三个部分 生产者、缓冲区、消费者 为什么生产者消费者模型要含三个部分?直接生产和消费不行么? 一个案例说明一切 生产者好比现实生活中的某个人 缓冲区好比现实生活中的邮箱 消费者好比现实生活中的邮递员 如果只有生产者和消费者, 那么相当于只有写信的人和邮递员,那么如果将来过去的邮递员离职

  • 本文向大家介绍java 中多线程生产者消费者问题详细介绍,包括了java 中多线程生产者消费者问题详细介绍的使用技巧和注意事项,需要的朋友参考一下 java 中多线程生产者消费者问题 前言: 一般面试喜欢问些线程的问题,较基础的问题无非就是死锁,生产者消费者问题,线程同步等等,在前面的文章有写过死锁,这里就说下多生产多消费的问题了 这个是jdk版本1.5以上的多线程的消费者生产者问题,其中优化的地

  • 本文向大家介绍基于C#实现的多生产者多消费者同步问题实例,包括了基于C#实现的多生产者多消费者同步问题实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了基于C#实现的多生产者多消费者同步问题,分享给大家供大家参考之用。具体代码如下: 希望本文所述对大家C#程序设计的学习有所帮助。

  • 我如何将电话限制在每5秒一次。注意:只能修改reallySlowApi。 编辑:我知道,但是如果Api变得更慢,它就不能解决问题。我需要使用的最佳方式。

  • 向Kafka推送100,000条消息 在使用者使用所有100,000条消息之前,使用Ctrl-C关闭zookeeper和kafka服务(这是通过在consumer方法中使用来模拟的)。 发现 在zookeeper和kafka服务被关闭后,消费者继续在控制台上写消息。 问题 我如何使消费者从上次消费的消息的索引+1继续。 向Kafka推送100,000条消息 在使用者使用所有100,000条消息之前

  • 尝试学习线程的多线程和进程间通信。实施了一个典型的生产者-消费者问题。然而,am获得的输出是相当连续的,这在理想情况下不应该是使用线程的情况。 好的,下面是完整的代码: 生产者线程: 使用者线程: 现在,当我运行程序时,生产者线程总是比消费者线程先运行。即使我创建了多个生产者/消费者,结果也是一样的。以下是单个生产者和单个消费者的产量: 有人能解释一下这里的行为吗?我已经在这里读了很多答案,但我想