簡體   English   中英

Java多線程-訪問“鎖定”對象時真正發生了什么?

[英]Java Multithreading - What Really Happens When Accessing A “Locked” Object?

給定以下對象,並在包裝​​器類中對其進行初始化:

// (thread-safe) List of Requests made by users
private static List<Request> requests = Collections.synchronizedList(new ArrayList<Request>());

在更新循環中不斷調用以下代碼:

// <-- (Thread 1 executes the following code @ Runtime=1.0000000ms)
    synchronized(requests) {
        for (Request request : requests)
            request.handle();
        requests.clear();
    }

而且這也“同時”發生。

// (Thread 2 executes the following code also @ Runtime=1.0000000ms)
    synchronized(requests) {
        (requests.add(new Request());
    }

據我了解,在這種情況下一定會發生以下情況:線程之一將成功鎖定請求列表,執行其各自的任務,並在退出同步塊時釋放其鎖定。

在我對“線程安全性”的理解中,這對我來說很奇怪。 可以說,盡管線程2試圖做同樣的事情,但線程1已經在請求列表上實現了鎖定並首先進入了它的同步塊。

1) 由於未實現對象的同步性而導致無法調用的同步塊內部的代碼發生了什么? (在這種情況下,使用線程2和該線程試圖將其添加到列表中的新Request()-發生了什么?-該請求是否只是在欺騙並且從不添加到請求列表中,因為線程1已鎖定賓語?

2) 線程2是否確實在等待線程1釋放其鎖定,並且在這種情況下,線程2重新查看了該對象並添加了請求? (假想的陷阱)如果是這種情況-如果線程1花60秒對列表中的所有Request對象執行handle()怎么辦-導致線程2等待那60秒?

額外的問題 )關於Collections.synchronizedList的1&2的答案是否與ConcurrentHashMap的行為相同?

1)由於未實現對象的同步性而導致無法調用的同步塊內部的代碼發生了什么?

其他線程將被阻塞,直到已獲取的線程釋放了鎖。 之后,保持線程釋放鎖,任何等待線程都可以獲取它。 獲得鎖的一個可以繼續進行,將不得不再次等待。

2)線程2是否確實在等待線程1釋放其鎖定,並且在這種情況下,線程2重新查看了該對象並添加了請求?

是的,線程2將必須等到線程1釋放鎖。 只有這樣,它才能獲取鎖。

每個鎖都有一個關聯的監視器,用於監控誰可以訪問與該鎖關聯的關鍵區域。 一次只有一個線程可以獲取此監視器,並且可以訪問關聯的關鍵區域。 所有其他線程將不得不等待獲取監視器。

暫無
暫無

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

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