gpt4 book ai didi

java - 如何在另一个线程JAVA中访问 volatile 变量

转载 作者:行者123 更新时间:2023-12-02 02:45:07 25 4
gpt4 key购买 nike

我正在尝试从多个正在运行的线程访问变量。

我有一个启动 2 个线程的主类,一个生产者和一个消费者。

PRODUCER 线程读取二进制文件。对于该二进制文件中的每一行,生产者线程从中创建一个对象,并通过阻塞队列将该对象传递给消费者线程。

然后,消费者获取通过阻塞队列传入的该对象,并将该对象中的字段值输出到文本文件。

有时生产者线程正在读取的二进制文件中存在错误。

当二进制文件中有太多错误时,我希望消费者线程将其输出的txt文件的扩展名更改为.err

我的问题:我不知道如何修改消费者线程中生产者线程的值。我一直在读到我可以使用 volatile 字段。但我不知道在线程之间使用它的正确方法是什么。

这是我的代码的一个非常简短且不太复杂的示例:

public class Main 
{

private volatile static boolean tooManyErrors= false;

public static void main(String[] args)
{

BlockingQueue<binaryObject> queue = new LinkedBlockingQueue<>(null);

binaryObject poison = null;

new Thread(new Producer(tooManyErrors, queue, poison)).start();
new Thread(new Consumer(tooManyErrors, queue, poison)).start();

}
}

public class Producer implements Runnable
{

private final BlockingQueue<binaryObject> queue;
private final binaryObject POISON;
private boolean tooManyErrors;

private int errorsCounter = 0;

public Producer(boolean tooManyErrors, BlockingQueue<binaryObject> queue,
binaryObject POISON)
{
this.tooManyErrors = tooManyErrors;
this.queue = queue;
this.POISON = POISON;
}

@Override
public void run()
{

try
{
process();
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
finally
{
while (true)
{
try
{
queue.put(POISON);
break;
}
catch (InterruptedException e)
{
//...
}
}
}

}

private void process() throws InterruptedException
{
//here is where all the logic to read the file and create
//the object goes in. counts the number of errors in the file
//if too many errors, want to change the tooManyErrors to true

if(errorsCounter > 100)
{
tooManyErrors = true;
}

}

}


public class Consumer implements Runnable
{

private final BlockingQueue<binaryObject> queue;
private final binaryObject POISON;
private boolean tooManyErrors;

//variable with extension name
private String extension;

public Consumer(boolean tooManyErrors, BlockingQueue<Integer> queue,
binaryObject POISON)
{
this.tooManyErrors = tooManyErrors;
this.queue = queue;
this.POISON = POISON;
}

@Override
public void run()
{

try
{
while (true)
{
binaryObject take = queue.take();
process(take);

// if this is a poison pill, break, exit
if (take == POISON)
{
break;
}
}
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}

}

private void process(Integer take) throws InterruptedException
{
//this is where all the logic goes that takes the binaryObject
//grabs all the fields from it such as binaryObject.getFileName,
//happens. It then outputs a text file with all the fields grabbed
//from the object. If the producer thread found too many errors
// I want the extension changed to .err instead of .txt
// I dont know how to do that

if(tooManyErrors == false)
{
extension = ".txt";

createFile(extension);
}
else
{
extension = ".err";

createFile(extension);
}
}

private void createFile(String extension)
{
//...
}

}

最佳答案

好的,这里有几件事。我假设只有一名生产者和一名消费者。如果是这种情况,您可以将类生产者和消费者标记为static。如果将该类标记为static,则其字段仅存在一个实例 - 它将是一个单例。您可以将生产者和消费者的任何字段标记为非私有(private),并且只需访问这些字段即可。来自消费者内部的 somethingINeed = Producer.fieldThatIsNotPrivate ,反之亦然。

另一种选择是保留所需对象的句柄并将其传递到构造函数中。

Producer p = new Producer(tooManyErrors, queue, poison);
Consumer c = new Consumer(tooManyErrors, queue, poison);
p.setConsumer(c);
c.setProducer(p);
new Thread(p).start();
new Thread(c).start();

您可以为任何需要共享信息的字段创建访问器。

关于java - 如何在另一个线程JAVA中访问 volatile 变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57151229/

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