簡體   English   中英

同步代碼塊

[英]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.

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