2016-09-07 55 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