[英]How can I access a volatile variable in another thread JAVA
我正在嘗試從多個運行線程訪問變量。
我有一個啟動2個線程的主類,一個生產者和一個消費者。
PRODUCER線程讀取一個二進制文件。 生產者線程為該二進制文件中的每一行創建一個對象,然后通過阻塞隊列將該對象傳遞給使用者線程。
然后,消費者將通過阻塞隊列傳入的對象獲取,並將該對象中字段的值輸出到文本文件。
有時,生產者線程正在讀取的二進制文件中有錯誤。
當二進制文件中有太多錯誤時,我希望使用者線程更改輸出到.err的txt文件的擴展名
我的問題:我不知道如何從使用者線程中的生產者線程修改值。 我一直在閱讀,我可以使用一個可變字段。 但是我不知道在線程之間使用它的正確方法是什么。
這是我的代碼的非常簡化且不太復雜的示例:
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
,則將僅存在其字段的一個實例-它將是單例。 您可以將生產者和使用者的任何字段標記為非私有,並且只需訪問這些字段即可。 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();
您可以為需要共享信息的任何字段創建訪問器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.