簡體   English   中英

Java靜態和線程安全

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM