问题描述
我是多线程技术的新手,使用相同类型的代码会遇到一些问题。
Integer key = mmybatisMapper.getkeyByUserName(userName); /// database call using mybatis to get key
PostProcessingTask postProcessingTask = new PostProcessingTask(key,userName);
Thread thread = new Thread(postProcessingTask);
thread.start();
//后处理代码
public class PostProcessingTask implements Runnable {
private final Integer key;
private final Integer name;
private ConcurrentMap<Integer,Integer> locks = new ConcurrentHashMap<Integer,Integer>();
public PostProcessingTask(final Integer key,final Integer name) {
this.key = key;
this.name = name;
locks.put(key,key);
}
@Override
public void run() {
try {
synchronized (locks.get(this.key)) {
///business logic
}
}
}
}
上面的代码可以很好地实现基于Integer值的同步。
但是,现在我再次尝试基于Integer值在另一个项目中实现同步,但该同步不起作用。 上面的代码和新的项目代码之间的唯一区别是,上面的代码是使用MyBatis从数据库获取Integer值,而我的新代码将使用来自REST端点请求的Integer值。
您能帮我解决基于REST端点请求中的值进行同步的问题吗?
解决方法
对synchronized
值进行Integer
是一个非常糟糕的主意,因为Integer.valueOf
对于[-128,127]以外的整数具有不同的行为,并且完全无关的代码位可能会同步在上面。在Integer
值上进行同步可能会发生不可预测的怪异事情。
不过,有一种简单的方法可以修改代码以完成您要执行的操作,那就是使用只是一个完全没有意义的Object
进行同步。编写locks.put(key,new Object())
,并保持其余代码不变。