簡體   English   中英

Java多線程非靜態和靜態方法的行為保持不變

[英]Java Multi threading Non Static and Static method behavior remains same

當我同步非靜態方法和靜態方法時,行為保持不變。 在兩種情況下,當我將synced(Task.class)都放入時,線程會同時為靜態和非staitc方法鎖定實例

public class ThreadDemo {
    public static void main(String[] args) {

        for(int i=0;i<10;i++){
            Task task =new Task();
            new Thread(task).start();
        }
    }
}
class Task implements Runnable {

    @Override
    public void run() {
        printThreadName();

    }

    public  void printThreadName() {
        synchronized (Task.class) {


        System.out.println("Starting-->"+Thread.currentThread().getName());
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Ending->"+Thread.currentThread().getName());
        }
    }

}

在將方法設為靜態之后

public  static  void printThreadName() {
        synchronized (Task.class) {


        System.out.println("Starting-->"+Thread.currentThread().getName());
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Ending->"+Thread.currentThread().getName());
        }
    }

每個線程都會鎖定該類,直到完成為止,依此類推。 我的問題是為什么在第一種情況下,即使對於非靜態方法,此行為也是如此。

我將總結以上評論:

JLS聲明以下內容:(我強調)

如果該方法是實例方法 ,則它將鎖定與其調用實例相關聯的監視器(即,在該方法的主體執行期間將被稱為此對象的對象)。 如果該方法是static ,則它將鎖定與Class對象關聯的監視器,該對象代表定義該方法的類。

因此,這將在實例上同步:

public synchronized void someMethod() { ... }

這將在類上同步:

public static synchronized void someMethod() { ... }

當您方法內部使用同步塊時,您需要提供監視器,該監視器可以是類(例如Myclass.class )或任何對象實例(可以是this ):

synchronized(monitor) { ... }

您可以使用synchronized(getClass())synchronized(this)來獲得與方法級同步非常相似的行為(我不確定getClass()變體在所有情況下的行為是否相同)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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