[英]Java Static and Thread safety
public class Thread1 extends Thread {
public static String data = "" ;
public Thread1(String tname){
super(tname);
}
public void run(){
synchronized (Thread1.data){
for (int i = 0; i < 5; i++) {
if(this.getName().equals("T1")){
Thread1.data = "Thread1";
try {
Thread.sleep(1000);
}catch (InterruptedException e){}
System.out.println(getName()+":"+Thread1.data );
}else if (this.getName().equals("T2")){
Thread1.data = "Thread2";
try {
Thread.sleep(1000);
}catch (InterruptedException e){}
System.out.println(getName()+":"+Thread1.data );
}
}
}
}
}
public class Main {
public static void main(String[] args) {
Thread a1 = new Thread1("T1");
Thread a2 = new Thread1("T2");
a1.start();
a2.start();
}
}
輸出:T2:Thread2
T1:線程2
T2:線程1
T1:線程2
T2:線程1
T1:線程2
T2:線程1
T1:線程2
T2:線程1
T1:線程1
怎么了 為什么不能將數據用作同步?
您重新分配data
的值。
Thread1.data = "Thread1";
// ...
Thread1.data = "Thread2";
這意味着, Thread1
獲得的鎖""
對象,然后Thread2
獲得的鎖"Thread1"
對象,它是一個完全不同的實體。 如果希望兩個線程在同一個對象上同步,則需要確保Thread1.data
不會更改其指向的對象。 最簡單的方法是擁有一個單獨的鎖對象。
public static final Object lock = new Object();
// Then, inside the function...
synchronized (Thread1.lock) {
// ...
}
由於永遠不會重新分配Thread1.lock
,因此它將始終引用相同的對象,並通過擴展引用相同的鎖。 將其定為final
將確保任何意外重新分配它的嘗試都將在編譯時失敗。
嘗試這個:
public void run() {
synchronized (Thread1.class) {
for (int i = 0; i < 5; i++) {
...
}
}
}
因為使用以下sendense時對象鎖定數據總是會更改:Thread1.data =“ Thread1”; 因此您不能忍受兩個線程同步。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.