[英]Java multithreading and global variables
我有一個Java類,它啟動了2個獨立的線程。 第一個線程啟動正常,所有變量都正確。
當我啟動第二個線程時,來自線程1的全局變量更改為線程2中設置的值。
我已經嘗試添加全局變量更新的同步塊,但這不起作用。
有沒有辦法解決這個問題? 我希望每個線程都啟動並使用自己的值而不會干擾其他線程值。
編輯:
我的Thread類的片段:
public abstract class ConsumerIF implements Runnable {
public static Element root = null;
public static String name = null;
public static String type = null;
public static String location = null;
public final synchronized void reconfigure() throws FatalDistributionException {
Document doc = builder.build(new StringReader(xmlCollector));
root = doc.getRootElement();
Element nameElement = root.getChild("name");
Element typeElement = root.getChild("type");
Element locationElement = root.getChild("location");
Element scheduleElement = root.getChild("schedule");
if (nameElement != null && typeElement != null && locationElement != null){
name = nameElement.getTextTrim();
type = typeElement.getTextTrim();
location = locationElement.getTextTrim();
}
}
}
靜態變量在所有線程之間共享,這就是使它們成為靜態的。 如果要使用不同的值,請使用ThreadLocals或(更好),在不同的線程中使用具有非靜態變量的不同對象。 沒有進一步的代碼,很難說更多。
同步僅控制線程對共享狀態的訪問。
如果你想要每個線程單獨的狀態,那么你需要為每個線程聲明該信息的不同實例(例如類)。 例如,只需在每個Thread
的run()
方法中實例化一個新對象,或者執行相關結構的副本(例如集合的深層副本)
另一種方法是調查ThreadLocal ,其中每個Thread將具有指定資源的不同副本。
如果您不希望共享變量,則不要使用全局變量(您可能在Java中表示static
)。 在線程啟動時初始化新對象,創建一個新字段。 例:
public class HelloThread extends Thread {
private MyObject myThreadVariable; // This is the thread-local variable
public void run() {
myThreadVariable = new MyObject(); // initialization when the thread starts
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new HelloThread()).start();
(new HelloThread()).start();
}
}
如果您確實需要在不同代碼段的本地訪問您的對象,請使用ThreadLocal
public class UniqueThreadIdGenerator {
private static final AtomicInteger uniqueId = new AtomicInteger(0);
// Value obtained from uniqueNum.get() will be thread-local even though uniqueNum is static
private static final ThreadLocal <Integer> uniqueNum = new ThreadLocal <Integer> () {
@Override protected Integer initialValue() {
return uniqueId.getAndIncrement();
}
};
public static int getCurrentThreadId() {
return uniqueNum.get();
}
}
同步的作用是它阻止兩個線程同時進入同步的代碼塊。 它也與在線程之間共享變量有關,但在相反的情況下 - 當你想要它們共享時。 如果沒有同步,您對一個線程的更改可能會或可能不會被其他線程看到(請參閱此處和此處 )
如果我理解正確,您應該查看final
修飾符:
private final String s;
這可以確保無法修改s
,因此您的線程將無法更改其值。
還要確保您的線程不會嘗試修改它們不應該修改的值,而是復制它們。
如果要使用靜態變量,則應在同步方法中的類對象上使用synchronized塊。
public abstract class ConsumerIF implements Runnable {
public static Element root = null;
public static String name = null;
public static String type = null;
public static String location = null;
public final synchronized void reconfigure() throws FatalDistributionException {
synchrnized(ConsumerIF.class) {
Document doc = builder.build(new StringReader(xmlCollector));
root = doc.getRootElement();
Element nameElement = root.getChild("name");
Element typeElement = root.getChild("type");
Element locationElement = root.getChild("location");
Element scheduleElement = root.getChild("schedule");
if (nameElement != null && typeElement != null && locationElement != null){
name = nameElement.getTextTrim();
type = typeElement.getTextTrim();
location = locationElement.getTextTrim();
}
}
}
}
確保從class object
上的同步方法/塊訪問所有靜態變量,而不是在實例變量或this
實例上訪問。 您使用的synchronized方法適用this
實例意味着您調用方法的當前對象和所有對象共享的靜態變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.