我在单身人士中有一个方法:
public void myMethod(String x){
//do lengthy process on x
}
我有三个线程正在调用myMethod
:
- 主题A,x =“单词” - >从05.00.01pm开始,在05.00.10pm结束
- 线程B,x =“句子” - >从05.00.01pm开始,在05.00.08pm结束
- 主题C,x =“单词” - >从05.00.02pm开始,在???
结束 醇>
正如您所见,Thread C
应该等到Thread A
完成,因为Thread C
也在发送word
。但是,Thread B
甚至可以在myMethod
完成之前执行Thread A
,因为它发送sentence
而不是word
。
myMethod
会经常被调用,parameter x
中的myMethod
没有规则,因此我认为保存parameter x
的所有可能值都不可行
仅供参考:虽然“x”参数的字符串长度不受限制,但字符保证仅为字母数字(a..zA..Z0..9),没有奇怪的重音字符 我该怎么做?
答案 0 :(得分:1)
您可以通过在方法
中基于String的规范表示形式放置一个synchronized块来实现此目的public void myMethod(String x){
synchronized(x.intern()){
//do lengthy process on x
}
}
答案 1 :(得分:0)
确保你需要有一个对象的hashmap来进行锁定,用函数参数键入:
Map<String,Object> locks=new HashMap<String,Object>();
public void myMethod(String x){
Object lock;
synchronized (locks) {
if ((lock=locks.get(x)) == null) locks.put(x, lock = new Object());
}
synchronized (lock) {
// do your staff
}
}
更新(已测试):
private Map<String,Object> locks=new HashMap<String,Object>();
public void getLock(String x) {
for (;;) {
Object lock;
synchronized (locks) {
lock=locks.get(x);
if (lock == null) {
locks.put(x, lock=new Object());
break;
}
}
try {
System.out.printf("Thread-%s locked\n",Thread.currentThread().getName());
synchronized (lock) {
lock.wait();
}
} catch (InterruptedException e) {}
}
}
public void unLock(String x) {
synchronized (locks) {
Object lock=locks.remove(x);
synchronized (lock) {
lock.notifyAll();
}
}
}
public void myMethod(String x){
getLock(x);
System.out.printf("Thread-%s start\n",Thread.currentThread().getName());
// do your staff
for (int i=0; i<30; ++i) {
System.out.printf("Thread-%s running %d\n", Thread.currentThread().getName(),i);
try {
Thread.sleep(10);
} catch (InterruptedException e) {}
}
System.out.printf("Thread-%s end\n",Thread.currentThread().getName());
unLock(x);
}
public void run() {
myMethod("abc");
}
public static void main(String[] args) {
final Test t = new Test();
Thread ths[] = new Thread[30];
for (int i=0; i < ths.length; ++i)
ths[i]=new Thread(t, String.valueOf(i));
for (int i=0; i < ths.length; ++i)
ths[i].start();
}