2016-09-07 45 views
0

我編寫了一個非常簡單的Java Web應用程序,只包含了一些基本功能,如註冊,登錄,更改密碼等。在java web中寫入併發文件的意外輸出

我不使用數據庫。我只是在應用程序中創建一個文件來記錄用戶的信息和數據庫的東西。

我用JMeter來強調web應用程序,特別是註冊接口。 JMeter的顯示,1000線的結果是正確的 enter image description here 但是當我看進information.txt,存儲用戶的信息,這是因爲它存儲700+記錄的錯誤: enter image description here

但應該包括1000條記錄,它必須在某處錯誤

我使用單例類來完成寫入/讀取的內容,並向類中添加同步字,insert()函數由寄存器用來記錄註冊信息如下圖所示:(其中一部分)

public class Database { 

private static Database database = null; 
private static File file = null; 


public synchronized static Database getInstance() { 

    if (database == null) { 
     database = new Database(); 
    } 

    return database; 
} 


private Database() { 

    String path = this.getClass().getClassLoader().getResource("/") 
      .getPath() + "information.txt"; 
    file = new File(path); 

    if (!file.exists()) { 
     try { 
      file.createNewFile(); 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } 
    } 

} 
public void insert(String account, String password, String username) { 

    RandomAccessFile infoFile = null; 

    try { 
     infoFile = new RandomAccessFile(file, "rw"); 
     String record; 
     long offset = 0; 

     while ((record = infoFile.readLine()) != null) { 
      offset += record.getBytes().length+2; 
     } 

     infoFile.seek(offset); 
     record = account+"|"+password+"|"+username+"\r\n"; 
     infoFile.write(record.getBytes()); 
     infoFile.close(); 

    } catch (IOException e) { 
     e.printStackTrace(); 

    } finally { 
     if (infoFile != null) { 
      try { 
       infoFile.close(); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
     } 
    } 


} 
} 

問題是爲什麼會發生這種情況,synchronized是線程安全的,爲什麼我丟失了這麼多的數據,並且插入了一些空白行,我該怎麼做才能正確使用它!

+1

Synchronized用於獲取對象的鎖定。由於在調用getInstance()(除了全局類級別鎖定)之外沒有對象,所以你正在使用'synchronized'作爲返回對象的方法,所以沒有同步'getInstance() '。你最好同步你的插入方法。 – hagrawal

+0

@hagrawal謝謝!我知道了! – wuxue

回答

1

您正在同步getInstance()方法,但不是insert()方法。這使得數據庫實例的線程安全的檢索,但不是寫入操作。

+0

謝謝!我知道了! – wuxue