猿问

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

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

我有一个启动 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;

       }


    }


}


梵蒂冈之花
浏览 106回答 1
1回答

动漫人物

好的,这里有几件事。我假设只有一个生产者和一个消费者。如果是这种情况,您可以将类生产者和消费者标记为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();您可以为需要共享信息的任何字段创建访问器。
随时随地看视频慕课网APP

相关分类

Java
我要回答