gpt4 book ai didi

java - 代码意外停止而不是无限运行

转载 作者:行者123 更新时间:2023-12-02 02:49:53 26 4
gpt4 key购买 nike

这是一个经典的排队问题。应该输入一个数字并得到相同的数字。这应该永远持续下去。

我的老师用这个问题来演示wait()的使用。但我的处理方式有所不同。

public class Q {
int n;
boolean Ready;
public Q()
{
Ready = false;
}
public void setReady(boolean ready) {
Ready = ready;
}
public boolean isReady() {
return Ready;
}
synchronized void put(int n)
{
this.n = n;
System.out.println("PUT:"+n);
}
synchronized int get()
{
System.out.println("GOT:"+n);
return n;
}
}

public class Producer extends Thread {

Q q;

public Producer(Q q) {
super();
this.q = q;
}

public void run()
{
int i=0;
for(;;)
{
if(!q.isReady())
{
q.put(i++);
q.setReady(true);
}
}
}
}

public class Consumer extends Thread {
Q q;

public Consumer(Q q) {
super();
this.q = q;
}



public void run()
{
for(;;)
{
if(q.isReady())
{
q.get();
q.setReady(false);
}
}
}
}

然后,在 main 中,我将同一个 Q 对象链接到消费者和生产者。然后我启动两个线程(消费者对象和生产者对象)。

代码在 48,84 等数字后停止。但我认为这应该是一个无限循环。

最佳答案

您的代码中存在多个问题。

首先,即使 getter 和 setter 也不是线程安全的。在生产者的 run() 的 for 循环主体中

if(q.isReady())
{
q.get();
q.setReady(false);
}
...

q.isReady() 和 if 的主体可能不会逐行执行。

  • 一个问题可能是 q.isReady() 对第一个线程返回 true,然后第二个线程正在获取句柄,也正在执行 q.isReady(),因此 if -> q.setReqady 的主体(假)被执行。
  • 第一个线程取回句柄,还执行了 q.get() 和 q.setReady(false) (因为线程返回了之前的位置),这是意料之外的。

有两种可能的方法可以解决这个问题:

<强>1。同步 getter 和 setter

public synchronized void setReady(boolean ready) {
Ready = ready;
}
public synchronized boolean isReady() {
return Ready;
}

<强>2。同步需要“原子”执行的部分

  • 此方法更容易出错,因为您必须从外部同步方法的使用。可能有不止一个地方执行相同的方法 - 您必须在各处同步它们。您可以通过将方法链放入“synchronized(ritical object) { ... }” block 中来实现此目的。所有线程的“对象实例”都会被锁定,直到同步的主体完全执行为止。

<强>3。您错误地执行了线程

  1. 由于您没有展示您的主要方法,我必须想象您是如何做到的。我的建议是启动多个消费者和生产者,这会导致同步错误。

如果你只启动一个生产者和一个消费者......

  • 您错误地启动了线程如果你的主要方法看起来像这样:

    ...
    消费者1.start();生产者1.start();}

  • 这里的问题是您没有等待线程完成。即使线程应该继续运行,您的主线程也会在启动其他线程后停止执行。JVM 将在某个时刻清理丢失的线程(它们不会永远运行,因为您丢失了它们的引用)。

    只需调用 Consumer1.join() 或 procer1.join() (或两者)即可修复此问题。

    关于java - 代码意外停止而不是无限运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57113619/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com