4 回答

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超9個(gè)贊
還是這段代碼會(huì)保證執(zhí)行過(guò)程永遠(yuǎn)不會(huì)在處理單個(gè)文件時(shí)嘗試中途關(guān)閉?
此代碼保證此處啟動(dòng)的關(guān)閉不會(huì)在處理單個(gè)文件的過(guò)程中發(fā)生。也許很明顯,您代碼中的其他地方可以調(diào)用System.exit
,而您對(duì)此沒(méi)有任何保護(hù)。
您可能需要考慮防止System.exit
被調(diào)用,然后讓您的代碼正常關(guān)閉(即通過(guò)方法的正常完成main
)。

TA貢獻(xiàn)1780條經(jīng)驗(yàn) 獲得超5個(gè)贊
萬(wàn)一你真的有多個(gè)線程調(diào)用不同的方法,synchronized這樣使用實(shí)際上是一個(gè)聰明的主意,因?yàn)樗幚砹恕岸嗑€程”的事情。
您可以考慮縮小第一個(gè)塊的范圍:
Path currentFileName = getNextFile();
String string = readFile(currentFileName);
synchronized(monitor) {
單獨(dú)讀取文件應(yīng)該不是問(wèn)題。(當(dāng)然,除非您此處的代碼必須保證由 返回的 PathgetNextFile()得到完全處理)。

TA貢獻(xiàn)1744條經(jīng)驗(yàn) 獲得超4個(gè)贊
如果代碼在synchronized
塊中執(zhí)行并且塊在同一個(gè)對(duì)象上同步,并且synchronized
循環(huán)中塊中調(diào)用的方法while
完全在與其調(diào)用者相同的線程上運(yùn)行,則不存在文件相關(guān)進(jìn)程被中斷的風(fēng)險(xiǎn)通過(guò)調(diào)用System.exit
. _
這就是說(shuō),它看起來(lái)確實(shí)像是一個(gè)有爭(zhēng)議的補(bǔ)丁,只是稍微改進(jìn)了有爭(zhēng)議的代碼。
可能還存在更具體的饑餓風(fēng)險(xiǎn),因?yàn)轱@示的 while 循環(huán)似乎盡可能快地向這些文件操作發(fā)送垃圾郵件,因此在退出時(shí)嘗試獲取鎖可能不會(huì)成功。
探索的一般方向是將無(wú)限while
循環(huán)轉(zhuǎn)換為ScheduledExecutorService
+ Runnable
,使用自己的監(jiān)視器執(zhí)行每 x 時(shí)間量以防止對(duì)相同文件的重疊操作,并在shutdown
調(diào)用該方法時(shí)優(yōu)雅地終止它。

TA貢獻(xiàn)1775條經(jīng)驗(yàn) 獲得超11個(gè)贊
您可以使用關(guān)閉掛鉤。來(lái)自 javadocs:
關(guān)閉掛鉤只是一個(gè)已初始化但未啟動(dòng)的線程。當(dāng)虛擬機(jī)開(kāi)始其關(guān)閉序列時(shí),它將以某種未指定的順序啟動(dòng)所有已注冊(cè)的關(guān)閉掛鉤,并讓它們同時(shí)運(yùn)行。
由此,您可以從您的文件類(lèi)中提供一個(gè)關(guān)閉掛鉤,如下所示:
public Thread getShutdownHook() {
? ? return new Thread(() -> {
? ? ? ? synchronized (monitor) {
? ? ? ? ? ? // gracefully handle the file object
? ? ? ? }
? ? });
}
這將在調(diào)用時(shí)調(diào)用Runtime.getRuntime().exit()(由 調(diào)用System.exit())。由于它也在監(jiān)視器對(duì)象上同步,如果其他線程正在使用該文件,關(guān)閉掛鉤將阻塞直到它空閑為止。
添加回答
舉報(bào)