为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

梵蒂冈之花 2023-04-13 10:53:30
我正在尝试从多个正在运行的线程访问变量。我有一个启动 2 个线程的主类,一个生产者和一个消费者。PRODUCER 线程读取一个二进制文件。对于该二进制文件中的每一行,生产者线程从中创建一个对象,并通过阻塞队列将该对象传递给消费者线程。CONSUMER 然后获取通过阻塞队列传入的对象,并将该对象中的字段值输出到文本文件。有时生产者线程正在读取的二进制文件中存在错误。当二进制文件中错误太多时,我希望消费者线程将其输出的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;       }    }}
查看完整描述

1 回答

?
动漫人物

TA贡献1815条经验 获得超10个赞

好的,这里有几件事。我假设只有一个生产者和一个消费者。如果是这种情况,您可以将类生产者和消费者标记为static. 如果将该类标记为static,则其字段的一个实例将仅存在 - 它将是一个单例。您可以将生产者和消费者的任何字段标记为非私有字段,然后只需访问这些字段即可。 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();

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



查看完整回答
反对 回复 2023-04-13
  • 1 回答
  • 0 关注
  • 105 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信