方法中一次只能有一个字符串

时间:2016-01-21 11:40:08

标签: java concurrency

我在单身人士中有一个方法:

public void myMethod(String x){
    //do lengthy process on x
}

我有三个线程正在调用myMethod

  
      
  1. 主题A,x =“单词” - >从05.00.01pm开始,在05.00.10pm结束
  2.   
  3. 线程B,x =“句子” - >从05.00.01pm开始,在05.00.08pm结束
  4.   
  5. 主题C,x =“单词” - >从05.00.02pm开始,在???
  6. 结束   

正如您所见,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),没有奇怪的重音字符 我该怎么做?

2 个答案:

答案 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();
}