Java 多线程环境中的数据不一致性
我创建了一个可以读写远程文件的应用程序。我在不同的目录(Java 多线程环境中的数据不一致性,java,multithreading,concurrency,concurrenthashmap,Java,Multithreading,Concurrency,Concurrenthashmap,我创建了一个可以读写远程文件的应用程序。我在不同的目录(文件夹-1,文件夹-2,文件夹-3)中有不同的文件(A.properties,B.properties,C.properties)。每个目录都有相同的文件名和不同的数据 我已经使用提供的LockRegistry在我的应用程序中实现了并发。问题是,如果一个线程正在访问a.properties,而另一个线程正在访问B.properties,则显示给最终用户的propertyMap将包含来自属性文件的两个数据。我如何解决这个问题 我的代码: pu
文件夹-1
,文件夹-2
,文件夹-3
)中有不同的文件(A.properties
,B.properties
,C.properties
)。每个目录都有相同的文件名和不同的数据
我已经使用提供的LockRegistry
在我的应用程序中实现了并发。问题是,如果一个线程正在访问a.properties
,而另一个线程正在访问B.properties
,则显示给最终用户的propertyMap
将包含来自属性文件的两个数据。我如何解决这个问题
我的代码:
public class UDEManager
{
private Map<String, String> propertyMap = new TreeMap<>();
HttpSession session = null;
public UDEPropertyManager()
{
super();
}
public void init(ServletConfig config) throws ServletException
{
super.init(config);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
// Code for calling thread for read/write operations into remote
// file and fill the propertyMap
}
}
class WebAppProperty implements Runnable
{
private WebApp webapp; // folder-1
private String propertyFile; // A.properties
private String keyValue; //messages-title=Messages
private LockType mode;
public String getPropertyFile()
{
return propertyFile;
}
public void setPropertyFile(String propertyFile)
{
this.propertyFile = propertyFile;
}
@Override
public void run()
{
try {
LockRegistry.INSTANCE.acquire(propertyFile, mode);
if (this.mode == LockType.WRITE) {
writeToPropertyFile();
} else if (this.mode == LockType.READ) {
getProperty(this.webapp, this.propertyFile);
}
} catch (Exception ie) {
sysoutAndLog("Thread is Interrupted");
ie.printStackTrace();
} finally {
LockRegistry.INSTANCE.release(propertyFile, mode);
}
}
private boolean getProperty(WebApp webapp, String property)
{
try {
// read from file and put it into Map instance variable
// of calling class (UDEManager)
propertyMap.put(key, value);
} catch(Exception e) {
sysoutAndLog("Error while reading property ");
e.printStackTrace();
}
return false;
}
private void writeToPropertyFile()
{
try {
// Write data into remote file
} catch (Exception e) {
sysoutAndLog("exception while writing to file.");
e.printStackTrace();
}
}
}
公共类管理器
{
私有映射属性Map=newtreemap();
HttpSession=null;
公共UDEPropertyManager()
{
超级();
}
public void init(ServletConfig config)抛出ServletException
{
super.init(config);
}
受保护的void doGet(HttpServletRequest请求、HttpServletResponse响应)
抛出ServletException、IOException
{
doPost(请求、响应);
}
受保护的void doPost(HttpServletRequest请求、HttpServletResponse响应)
抛出ServletException、IOException
{
//用于调用线程进行远程读/写操作的代码
//归档并填写属性映射
}
}
类WebAppProperty实现可运行
{
私有WebApp WebApp;//文件夹-1
私有字符串propertyFile;//A.properties
私有字符串keyValue;//消息标题=消息
私有锁式模式;
公共字符串getPropertyFile()
{
返回属性文件;
}
公共void setPropertyFile(字符串propertyFile)
{
this.propertyFile=propertyFile;
}
@凌驾
公开募捐
{
试一试{
LockRegistry.INSTANCE.acquire(propertyFile,模式);
if(this.mode==LockType.WRITE){
WritePropertyFile();
}else if(this.mode==LockType.READ){
getProperty(this.webapp、this.propertyFile);
}
}捕获(例外情况即){
sysoutAndLog(“线程被中断”);
即printStackTrace();
}最后{
LockRegistry.INSTANCE.release(propertyFile,模式);
}
}
私有布尔getProperty(WebApp WebApp,字符串属性)
{
试一试{
//从文件中读取并将其放入映射实例变量中
//调用类(UDEManager)的名称
属性映射put(键、值);
}捕获(例外e){
sysoutAndLog(“读取属性时出错”);
e、 printStackTrace();
}
返回false;
}
私有无效writeToPropertyFile()
{
试一试{
//将数据写入远程文件
}捕获(例外e){
sysoutAndLog(“写入文件时异常”);
e、 printStackTrace();
}
}
}
您确实意识到servlet及其字段由所有请求共享,对吗?您需要将映射与请求或用户会话相关联。谢谢Mark,它通过将映射与关联而起作用session@AnsarSamad那么就把它作为一个答案