Java中的保护块跟踪

Java中的保护块跟踪,java,concurrency,Java,Concurrency,我已经为这个简单的并发Oracle问题挣扎了几天,这个问题为生产者/消费者建模。这是我第一次使用防护块,等等,等等。然而,我知道这些方法的作用;我不知道先发生什么步骤。我将尽我所能在下面追踪这个问题,你们可以告诉我我是否正确 生产者/消费者线程从主线程开始。每个实例都有相同的Drop实例 如果使用者线程比生产者线程快,则其会在drop时获取内在锁,并尝试在循环中从drop.take()打印消息。但是,由于empty为真,生产者没有向消费者提供消息。这将导致线程被挂起,锁被释放。它正在等待 生产者

我已经为这个简单的并发Oracle问题挣扎了几天,这个问题为生产者/消费者建模。这是我第一次使用防护块,等等,等等。然而,我知道这些方法的作用;我不知道先发生什么步骤。我将尽我所能在下面追踪这个问题,你们可以告诉我我是否正确

  • 生产者/消费者线程从主线程开始。每个实例都有相同的Drop实例
  • 如果使用者线程比生产者线程快,则其会在drop时获取内在锁,并尝试在循环中从
    drop.take()
    打印消息。但是,由于
    empty
    为真,生产者没有向消费者提供消息。这将导致线程被挂起,锁被释放。它正在等待
  • 生产者线程在循环中调用
    drop.put()
    。由于
    empty
    为true,它需要为消费者准备消息,因此在drop时获取内在锁并继续该方法。它将
    empty
    设置为false并存储消息<调用code>notifyAll(),唤醒使用者线程。生产者也在等待,因为
    empty
    现在为false,锁被释放
  • 由于通知了
    drop.take()
    ,并且生产者对drop具有内在锁定,因此它会唤醒该方法
    Empty
    被设置为true,消息将返回并在循环中打印。它现在通知生产者线程唤醒,因为它需要一条新消息
  • 制片人一直在等待。由于
    empty
    为true,并且线程已被通知(并且锁已被访问),因此它现在可以唤醒并生成另一条消息 辍学

    包装店;
    公务舱降落{
    //从生产者发送的消息
    //给消费者。
    私有字符串消息;
    //如果消费者应该等待,则为True
    //让制作人发送消息,
    //如果生产者应等待,则为false
    //消费者检索消息。
    私有布尔值为空=真;
    公共同步字符串take(){
    //等待消息被删除
    //可用。
    while(空){
    试一试{
    等待();
    }捕获(中断异常e){}
    }
    //切换状态。
    空=真;
    //通知制片人
    //状态已更改。
    notifyAll();
    返回消息;
    }
    公共同步的void put(字符串消息){
    //等待消息已发送
    //已经找回了。
    而(!空){
    试试{
    等待();
    }捕获(中断异常e){}
    }
    //切换状态。
    空=假;
    //存储消息。
    this.message=消息;
    //通知消费者该状态
    //已经改变了。
    notifyAll();
    }
    
    }
    我没有完整的答案,但我有一些观察结果

    包装等待时,如果出现异常循环,则会导致异常。wait需要锁,但wait会释放锁。幸运的是,你不应该经历这种行为

    您可能会遇到实例变量没有跨线程更新的问题。您需要同步,然后等待。这为这些变量提供了具有不同值的机会。将它们标记为易失性将有助于实现这一点


    你没有说你的代码实际上做了什么…

    我只是在跟踪第一条消息的步骤,这将对其他消息重复。我喜欢你说的等待是如何要求和释放锁的。