[英]Synchronizing a block of code
我有一段Java代碼,如果不存在的話會在文件系統中創建一個目錄。 此應用程序是多線程的(有2個線程運行),因此有時會發生以下情況:檢查if(!dir.exists())
對兩個線程都返回true,然后在內部代碼中調用dir.mkdirs()
返回true從而創建了目錄,另一個返回false,讓我向您展示代碼:
public void makePath(){
File path = new File(Main.getPath());
synchronized (this) {
if (!path.exists()) {//return true on both treads
if (path.mkdirs()) {//return true only on one thread
logger.warn("Path was not existing, just created one");
} else {//returns false only on one thread
logger.warn("Problems while creating pth");
}
}
}
}
我的初始版本沒有同步塊,我認為這可以解決問題,但事實並非如此。 當我使用單線程運行時,一切正常,使用單線程!path.exists()
僅返回true。
這是因為您在內部類中進行同步。
synchronized (this)
一定不是this
,它可能是此方法之外的其他對象,例如它可以是字段
您可以像這樣更改代碼:
synchronized (Foo.class)
如果您在同步this
(無論類的當前實例定義的方法),那么這並不妨礙另一個實例同時運行同一個塊,因為它將對自身進行同步。 您需要在同一對象上同步。
例如
private static Object syncKey = new Object();
public void makePath() {
synchronized (syncKey) {
...
}
}
我已修復了將函數委派給創建文件或檢查文件是否存在的問題。 然后,可調用實例調用此方法,而不是自己創建文件
/**
* Create a directory and its sub directories in a synchronized way
*
* @param file
* @return
*/
public static synchronized boolean createDirsIfNecessary(String path) {
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
return true;
}
return false;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.