第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java 是否保證當(dāng)前同步的對象不會被垃圾回收?

Java 是否保證當(dāng)前同步的對象不會被垃圾回收?

喵喔喔 2023-07-19 16:50:55
當(dāng)線程持有其監(jiān)視器時,是否可以保證對象不會被垃圾收集?例如class x {    private WeakReference<Object> r;    Object getMonitorObject() {        Object o = new Object();        r = new WeakReference<>(o);        return o;    }    void thread1() throws Exception {        synchronized (getMonitorObject()) {            Thread.sleep(3000);        }    }    void thread2() {        Object b = r.get();    }}具體來說,在這種情況下,是否有任何保證在另一個線程正在休眠時b將被調(diào)用非nullif ?我們假設(shè)整個過程是在另一個線程休眠時執(zhí)行的。thread2()thread1()thread2()thread1()
查看完整描述

5 回答

?
紅顏莎娜

TA貢獻(xiàn)1842條經(jīng)驗 獲得超13個贊

同步可以防止垃圾收集,但一般情況下不會。對于您的具體情況,我們無法保證。

與JLS §12.6.1比較

這種類型的轉(zhuǎn)換可能會導(dǎo)致該finalize方法的調(diào)用比預(yù)期的更早發(fā)生。為了允許用戶防止這種情況,我們強(qiáng)制執(zhí)行同步可以使對象保持活動狀態(tài)的概念。如果一個對象的終結(jié)器可以導(dǎo)致該對象上的同步,那么只要對該對象持有鎖,該對象就必須處于活動狀態(tài)并且被認(rèn)為是可訪問的。

請注意,這不會阻止同步消除:同步僅在終結(jié)器可能對其進(jìn)行同步時才使對象保持活動狀態(tài)。由于終結(jié)器發(fā)生在另一個線程中,因此在許多情況下無論如何都無法刪除同步。

因此,由于您的對象沒有自定義終結(jié)器,因此在終結(jié)過程中可能不會發(fā)生同步,原則上,您的對象是一個允許消除鎖的臨時對象,在這種情況下,它不會阻止垃圾收集。

但是存在一個實際障礙,即您存儲 a 的WeakReference方式使得另一個線程可以在未收集該對象時檢索該對象,一旦存在這種可能性,該對象就不再是本地的,并且無法應(yīng)用鎖消除。

在構(gòu)造后立即積極收集對象(或完全消除其存在)并在其逃逸或WeakReference首先創(chuàng)建空對象之前清除弱引用的理論實現(xiàn)將符合規(guī)范,就像在該執(zhí)行場景中一樣,鎖消除是有道理的。


請注意,即使您插入 a ,線程調(diào)用和另一個調(diào)用reachabilityFence之間也沒有發(fā)生之前關(guān)系,因此第二個線程可能始終表現(xiàn)得好像在另一個線程完成塊或通過可達(dá)性柵欄之后執(zhí)行,即使您的真實線程生命時鐘卻另有說明。明確表示沒有同步語義。thread1()thread2()thread2()synchronizedThread.sleep


查看完整回答
反對 回復(fù) 2023-07-19
?
12345678_0001

TA貢獻(xiàn)1802條經(jīng)驗 獲得超5個贊

為了讓synchronized塊的末尾刪除監(jiān)視器鎖,該synchronized塊必須保留對返回的對象的引用getMonitorObject()。

該引用會阻止 GC,所以答案是肯定的。


查看完整回答
反對 回復(fù) 2023-07-19
?
慕森卡

TA貢獻(xiàn)1806條經(jīng)驗 獲得超8個贊

在我詳細(xì)研究過的所有 Java 實現(xiàn)中,對象的原始互斥體或鎖的狀態(tài)在第1部分中由對象頭中的位表示。當(dāng)鎖被釋放時,JVM 需要更新標(biāo)頭位2,因此它仍然必須擁有對該對象的引用,無論是在堆棧上還是在寄存器中。

1 - 當(dāng)發(fā)生互斥鎖爭用時,鎖會“膨脹”以記錄額外信息。所以我們不能說整個狀態(tài)都在對象頭中。

2 - 在大多數(shù)情況下,解鎖代碼不知道鎖定對象是否不可訪問。但如果它是由于積極的 JIT 編譯器優(yōu)化而實現(xiàn)的,那么假設(shè)它也可以知道不再需要更新對象頭。


但是假設(shè)解鎖互斥體時未使用/不需要對象引用。

以下是JLS 12.6.1中可達(dá)性的定義:

可到達(dá)的對象是可以在任何潛在的持續(xù)計算中從任何活動線程訪問的任何對象?!?“可以通過某些引用鏈從某些可終結(jié)的對象到達(dá)終結(jié)器可到達(dá)的對象,但不能從任何活動線程到達(dá)?!?/em>

“任何一種方法都無法到達(dá)無法到達(dá)的對象?!?/em>

為了使對象成為垃圾收集的候選對象,它必須不可訪問。換句話說,它不能從任何活動線程訪問。

鎖定的互斥鎖怎么樣?好吧,線程的“潛在的持續(xù)計算”可能需要解鎖互斥鎖:

  • 如果互斥鎖在沒有對象引用的情況下無法解鎖,則該對象是可達(dá)的。

  • 如果可以在不引用對象的情況下解鎖互斥鎖,那么該鎖可能無法訪問,或者終結(jié)器可訪問。


可是等等 ...

在JLS 12.6.2中,有一些關(guān)于可達(dá)性決策點(diǎn)的復(fù)雜語言。

“在每個可達(dá)性決策點(diǎn),某些對象集被標(biāo)記為不可達(dá),而這些對象的某些子集被標(biāo)記為可終結(jié)?!?/p>

" 如果對象 X 在 di 處被標(biāo)記為不可訪問,則: - ... - 在 di 之后的線程 t 中對 X 的所有主動使用都必須發(fā)生在 X 的終結(jié)器調(diào)用中,或者作為線程 t 執(zhí)行讀取的結(jié)果出現(xiàn)在對 X 的引用的 di 之后;并且 - ...”

“當(dāng)且僅當(dāng)以下至少一項為真時,操作a才是主動使用: - ... -?鎖定或解鎖?,并且?在調(diào)用終結(jié)器之后發(fā)生鎖定操作. - .. ”。XaXXX

現(xiàn)在,如果我理解正確的話,那就是說,如果活動線程仍然可以釋放相應(yīng)的互斥鎖,那么可終結(jié)的對象就無法被終結(jié)。


總之:

  1. 在當(dāng)前的 JVM 中,互斥鎖的鎖定狀態(tài)取決于對象頭。如果互斥體仍然可以被線程釋放,那么該對象必須是可訪問的......作為實現(xiàn)細(xì)節(jié)。

  2. 假設(shè)存在一個 JVM,其中可以在不引用對象的情況下釋放互斥鎖,那么當(dāng)對象仍處于鎖定狀態(tài)時,該對象可能無法訪問。

  3. 但是,如果該對象是可終結(jié)的,那么直到所有可能需要釋放鎖的活動(應(yīng)用程序)線程都完成了該操作之后,該對象才會被終結(jié)。


查看完整回答
反對 回復(fù) 2023-07-19
?
一只名叫tom的貓

TA貢獻(xiàn)1906條經(jīng)驗 獲得超3個贊

我剛剛在javadoc中看到了這樣的“旁白”:

reachabilityFence“在本身確保可訪問性的構(gòu)造中不需要[方法]。例如,因為通常無法回收鎖定的對象,所以如果在類 Resource 的所有方法(包括Finalize)被包含在同步(this)塊中。”

這似乎是說,被鎖定的對象不能被垃圾收集。

我不確定這是否優(yōu)先于 JLS 12.6.1 和 12.6.2;請參閱我的其他答案,或者我們是否應(yīng)該將其理解為僅適用于 Oracle / OpenJDK Java 類庫的 Java(語言)實現(xiàn)。


查看完整回答
反對 回復(fù) 2023-07-19
?
RISEBY

TA貢獻(xiàn)1856條經(jīng)驗 獲得超5個贊

sleep 方法不會離開同步塊,因此不會釋放鎖或監(jiān)視器對象,它只是阻塞執(zhí)行一段時間。由于鎖從未被釋放,垃圾收集器不會收集它,除非持有它的線程完成同步塊的執(zhí)行或使用wait()方法釋放它。

所以,是的,如果有足夠的時間完成thread2()調(diào)用,它保證不為空。thread1()getMonitorObject()

查看完整回答
反對 回復(fù) 2023-07-19
  • 5 回答
  • 0 關(guān)注
  • 232 瀏覽

添加回答

舉報

0/150
提交
取消