2012-08-15 70 views
7

從我所瞭解和研究的結果來看,Java中的​​關鍵字允許同步方法或代碼塊語句以處理多線程訪問。如果我想鎖定文件以便在多線程環境中進行寫入,則I 必須 應該使用Java NIO package中的類來獲得最佳結果。昨天,我提出了一個關於處理文件I/O操作的共享servlet的問題,BalusC的評論很好的幫助解決了這個問題,但this answer中的代碼讓我感到困惑。我並沒有要求社區「燒掉那個帖子」或「讓我們冷靜點他」(注意:我沒有降低它或任何東西,並且我沒有任何反對的答案),我要求解釋一下,如果代碼片段可以被認爲是一個很好的做法同步文件對象

private static File theFile = new File("theonetoopen.txt"); 

private void someImportantIOMethod(Object stuff){ 
    /* 
     This is the line that confuses me. You can use any object as a lock, but 
     is good to use a File object for this purpose? 
    */ 
    synchronized(theFile) { 
     //Your file output writing code here. 
    } 
} 
+1

+1,因爲現在你已經超過4000人。 – Hassan 2012-08-15 19:53:20

+1

@Hassan無論是誰,無論它是什麼聲望,都不要這樣做,直到你覺得問題/答案是有幫助的。 – 2012-08-15 19:55:31

+0

@Nandkumar我喜歡這個問題,我只是覺得這很有趣。 – Hassan 2012-08-15 19:57:11

回答

4

的問題是不是鎖定一個文件對象上 - 你可以鎖定任何物體上,它並不真正的問題(在某種程度上)。

讓我感到震驚的是,您使用的是非最終顯示器,因此如果代碼的另一部分重新分配文件:theFile = new File();,下一個出現的線程將鎖定另一個對象,並且您沒有任何擔保你的代碼不會再被兩個線程同時執行。

如果已經最終確定了theFile,代碼將會正常,但最好使用私人顯示器,以確保沒有其他鎖定目的的代碼可以使用。

+0

是的,我敢肯定,在這種情況下,鎖是一個文件(除了失蹤的'最後',如由亞爾指出的那樣)並不重要。如果有的話是代碼混亂,因爲它暗示了JRE的土地和文件系統之間的某種聯繫,當時(可能)不是其中的一種。 – dsummersl 2012-08-15 20:02:59

+0

是的,'final'關鍵字會有所作爲,正如在帖子[如何在Java中同步?](http://javarevisited.blogspot.com/2011/04/synchronization-in-java-synchronized.html )。讓我感到困惑的是使用File對象鎖定代碼塊,事實上我對Java鎖和文件上的操作系統鎖感到困惑,但我想這些鎖非常不同。 – 2012-08-15 20:09:08

1

你見過:final Object lock = new Object()你會問嗎?
正如@assylias指出的問題是鎖不是final這裏

1

Java中的每個對象都可以充當同步的鎖。它們被稱爲內部鎖。一次只有一個線程可以執行由給定的鎖保護的代碼塊。

更多的是:http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

使用整個方法synchronized關鍵字可能對您的應用程序性能的影響。這就是爲什麼你有時可以使用同步塊。

您應該記住鎖定參考不能更改。最好的解決方案是使用final關鍵字。

2

如果您只需要在單個應用程序中鎖定該文件,那麼就可以了(假設添加了final)。

請注意,如果您使用不同的類加載器多次加載類,該解決方案將不起作用。例如,如果您的Web應用程序在同一個Web服務器上部署了兩次,則應用程序的每個實例都將擁有自己的鎖定對象。正如你所提到的,如果你希望鎖定功能強大並且鎖定了其他程序,你應該使用FileLock(請參閱文檔,在某些系統中,並不保證所有程序都必須遵守該鎖定) 。