0

我想在对象上使用一种只打印尚未收到的数字的方法,因此我使用了以下代码。这个想法是我使用一个映射,它为每个整数存储一个锁,如果它已经在映射中,则线程等待锁,否则它将以该整数作为键和Integer对象作为新的锁到映射中价值,

注意:我Integer(a)用作整数的锁a

问题是我想释放地图的锁,我想等待从地图中检索到的锁,但是race condition发生了,有什么想法可以解决这个问题吗?

public class sync_print {
    public static void main(String[] args) {
        sync_print syobj = new sync_print();
        Thread t1 = new Thread(new worker(syobj, 10) , "thread 1");
        Thread t2 = new Thread(new worker(syobj, 10) , "thread 2");
        Thread t3 = new Thread(new worker(syobj, 4) , "thread 3");
        Thread t4 = new Thread(new worker(syobj, 5) , "thread 4");
        Thread t5 = new Thread(new worker(syobj, 5) , "thread 5");
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
    }


    HashMap<Integer, Integer> lock_map = new HashMap<Integer , Integer>();
    void print(int a) throws InterruptedException{
        synchronized(lock_map){
            Integer lock = lock_map.get(a);
            if (lock != null){
                synchronized (lock) {
                    System.out.println(Thread.currentThread().getName() + " is waiting");
                    lock_map.notify();
                    lock.wait();
                }
            }else{
                lock_map.put(a, new Integer(a));
                System.out.println(a);
            }
        }
    }
}

class worker implements Runnable{
    int val;
    sync_print obj;
    public worker(sync_print obj , int v){
        this.val = v;
        this.obj = obj;
    }
    public void run() {
        try {
            obj.print(val);
        } catch (InterruptedException e) {}
    }
}
4

2 回答 2

0

You might be able to eliminate the lock on lock_map by replacing your HashMap with a ConcurrentHashMap. Change lock_map.put to lock_map.putIfAbsent.

于 2013-06-21T18:44:58.633 回答
0

wait不在循环内。请参阅其他地方了解为什么会产生问题。

于 2013-06-21T18:55:40.853 回答