我想確認這個我的理解 -多線程:線程獲取方法的自己的副本,但參數是共享
public class Main {
private static int j = 0;
private int k = 0;
public static void main(String[] args) {
Main obj = new Main();
obj.doProcess();
}
public void doProcess() {
ExecutorService service = Executors.newFixedThreadPool(10);
for (int i = 0; i < 4; i++) {
service.submit(new SingleProcessor());
}
}
public static void myStaticMethod() {
System.out.println("my static method");
int i = 0;
i++;
j++;
System.out.println("i " + i);
System.out.println("j " + j);
}
public void myInstanceMethod() {
System.out.println("my instance method");
int i = 0;
i++;
k++;
System.out.println("k " + k);
}
private class SingleProcessor implements Runnable {
@Override
public void run() {
System.out.println("single run starts" + Thread.currentThread().getName());
myStaticMethod();
myInstanceMethod();
}
}
}
當一個線程運行時,它得到它的方法自己的副本,無論是靜態的或實例方法 - 在這些方法中創建的任何變量都是本地的,並且是特定於該線程的。這就像這個方法的多個'實例'被同時執行一樣,任何在裏面創建的變量都不會被共享(它是本地的)。
但是參數(靜態或實例)由線程共享。
所以在上面的例子 - 我是本地和特定於線程。 j是共享的。 k是共享的。
輸出 -
single run startspool-1-thread-1
single run startspool-1-thread-2
my static method
single run startspool-1-thread-3
my static method
i 1
i 1
j 2
j 2
my instance method
my instance method
k 1
k 2
my static method
i 1
j 3
my instance method
k 3
single run startspool-1-thread-4
my static method
i 1
j 4
my instance method
k 4
我的理解是100%正確的?任何人都想用更好的話來表達它?
謝謝。
我不認爲比較一個靜態變量與單例是一個好主意。靜態變量用於單例的事實是一種做法。如果不是最終的,則可以更改靜態變量。另外,我不認爲答案是關鍵的(例如討論stack vs heap) – 2014-09-02 23:26:54
也許沒錯,我不應該使用Singleton這個詞。我試圖做一個'metaphore',以表明在內存中,任何線程都會使用相同的引用。它可能會令人困惑。 – JSlain 2014-09-03 01:09:15
那是不正確的。一個靜態變量不會被java的內存模型區別對待。線程將得到一個副本,也沒有同步能見度的最新更新不保證 – eldjon 2014-09-03 08:55:23