java中互斥锁的有关问题: 当几个参数对象的所有属性值相同时就上互斥锁
java中互斥锁的问题: 当几个参数对象的所有属性值相同时就上互斥锁
这个问题其实我在百度上面已经问过,但是没人回应,所以..
还请大家帮帮忙哈
言归正传,问题:
例如:
我做的是web开发,当我开两个浏览器对同一个对象进行 doSomething 操作时,发现它们不会互斥
我想大概是这两个值相同的对象不是同一对象的原因吧, 求大神帮忙想想办法,如何才能让两个person对象的所有属性值相同的时候就互斥. 谢谢!
谢谢! 我刚刚测了一下,找到了答案,可以利用String对象的特殊性来进行上锁,
因为对象的id是唯一的,所以可以用对象的id来作为锁对象. String :对于所有的拥有相同值的String对象,只会创建一个String对象.
代码如下:
这样对于拥有相同属性的和属性值的不同的person对象来说,就可以进行互斥啦!
//但是 我如果不在synchronized块上面定义 id 对象,而直接调用getId方法来作为锁对象就不能互斥了: 这是为什么了?
--上面写的是在一个测试类里面的,但是刚刚在项目中试了一下,居然用String也不可以... (这个方法是写在Service里面的),这是测试类和在web中的环境不同造成的吗?
------解决方案--------------------
person.getId()只是取到的值是一样的 引用又不是同一个 因为每次访问都是new 一个Person
要同步需要用外部变量做同步 你可以用一个静态成员变量
------解决方案--------------------
我不知道你的Person对象中的ID属性是怎么赋值的,你如果定义了一个String id的话JVM会进行缓存,所以...
String s1 = "abc";
String s2 = "abc";
这样两句,对JVM来说都是同一个对象.
------解决方案--------------------
ConditionalLock.java
这个问题其实我在百度上面已经问过,但是没人回应,所以..
还请大家帮帮忙哈
言归正传,问题:
例如:
public void doSomething(Person person){
synchronized(person){
system.out.println("start: "+person.getId());
Thread.sleep(5000);
system.out.println("end: "+person.getId());
}
}
我做的是web开发,当我开两个浏览器对同一个对象进行 doSomething 操作时,发现它们不会互斥
我想大概是这两个值相同的对象不是同一对象的原因吧, 求大神帮忙想想办法,如何才能让两个person对象的所有属性值相同的时候就互斥. 谢谢!
谢谢! 我刚刚测了一下,找到了答案,可以利用String对象的特殊性来进行上锁,
因为对象的id是唯一的,所以可以用对象的id来作为锁对象. String :对于所有的拥有相同值的String对象,只会创建一个String对象.
代码如下:
public void doSomething(Person person){
String id=person.getId();
synchronized(id){
...
}
}
这样对于拥有相同属性的和属性值的不同的person对象来说,就可以进行互斥啦!
//但是 我如果不在synchronized块上面定义 id 对象,而直接调用getId方法来作为锁对象就不能互斥了: 这是为什么了?
//String id=person.getId();
synchronized(person.getId()){
....
}
--上面写的是在一个测试类里面的,但是刚刚在项目中试了一下,居然用String也不可以... (这个方法是写在Service里面的),这是测试类和在web中的环境不同造成的吗?
------解决方案--------------------
person.getId()只是取到的值是一样的 引用又不是同一个 因为每次访问都是new 一个Person
要同步需要用外部变量做同步 你可以用一个静态成员变量
------解决方案--------------------
我不知道你的Person对象中的ID属性是怎么赋值的,你如果定义了一个String id的话JVM会进行缓存,所以...
String s1 = "abc";
String s2 = "abc";
这样两句,对JVM来说都是同一个对象.
------解决方案--------------------
ConditionalLock.java
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionalLock {
private final static Map<Thread, Person> relations = new ConcurrentHashMap<Thread, Person>();
private final static ReentrantLock lock = new ReentrantLock(false);
private final static Condition condition = lock.newCondition();
private Person person;
public ConditionalLock(Person p) {
this.person = p;
}
public void await() {
lock.lock();
try {
while (isAlreayLocked()) {
condition.await();
}
relations.put(Thread.currentThread(), person);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void singal() {
lock.lock();
try {
condition.signal();
relations.remove(Thread.currentThread());
} finally {
lock.unlock();
}
}
private boolean isAlreayLocked() {
Set<Entry<Thread, Person>> sets = relations.entrySet();
for (Entry<Thread, Person> entry : sets) {
Person other = entry.getValue();
if (other == null) {
continue;
}
if (this.person.equals(other)) {
return true;