假设有两个线程,线程1和线程2,运行如下代码,起的作用是如果数据区中已存在,则不保存
public Tag saveTag(Tag tag) {
synchronized (tag) {
if (contains(tag)) {
return null;
}
return dao._save(tag);
}
}
线程1和2分别运行此方法save tag1和tag2
而tag1和tag2,tag1和tag2中内容完全相同且Tag类已写了equals和hashcode方法
我的问题是这么写,锁定tag,能起作用吗?jvm会判断tag1和tag2是同一个tag吗?
------解决思路----------------------
public class T {
public static void main(String[] args) {
Person p=new Person();
Person p1=new Person();
System.out.println( p.equals(p1));//true
System.out.println( p==p1);//false
}
}
class Person{
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
return true;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return 1;
}
}
锁不住
------解决思路----------------------
你的锁显然不是同一个对象,即使你重写了hashCode()和equals()方法,这两个对象在堆上的地址依然是不一样的。
锁应该具有唯一性。
------解决思路----------------------
synchronized (this)
//或者
public synchronized Tag saveTag(Tag tag) {
if (contains(tag)) {
return null;
}
return dao._save(tag);
}
看一下锁的概念,加锁是对哪个对象加锁,每次传入的tag对象不是同一个对象,thread1、thread2 在执行加锁代码块时,获取的就是不同对象的锁。
注意点:saveTag方法的对应对象,不能在thread1、thread2 中new 出来,然后在调用saveTag,否者获取的锁又不是同一对象的锁,可以实现单例。
------解决思路----------------------
判断是否同一个锁和equals hash什么的无关,只有==成立,他们才是一个锁