Java 释放地图的锁并获取值的锁

Java 释放地图的锁并获取值的锁,java,multithreading,locking,Java,Multithreading,Locking,我想在对象上有一个只打印尚未收到的数字的方法,因此我使用了下面的代码。我的想法是,我使用一个映射,它为每个整数存储一个锁,如果它已经在映射中,线程将等待一个锁,否则它将在映射中放入一个新锁,以该整数作为键,以整数对象作为值 注意:我使用Integer(a)作为Integera的锁 问题是我想释放地图的锁,我想等待从地图中检索到的锁,但是出现了一个竞争条件,有什么办法解决这个问题吗 public class sync_print { public static void main(Stri

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

注意:我使用
Integer(a)
作为Integer
a的锁

问题是我想释放地图的锁,我想等待从地图中检索到的锁,但是出现了一个
竞争条件
,有什么办法解决这个问题吗

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) {}
    }
}
公共类同步\u打印{
公共静态void main(字符串[]args){
sync_print syobj=新的sync_print();
线程t1=新线程(新工作线程(syobj,10),“线程1”);
线程t2=新线程(新辅助线程(syobj,10),“线程2”);
线程t3=新线程(新工作线程(syobj,4),“线程3”);
线程t4=新线程(新工作线程(syobj,5),“线程4”);
螺纹t5=新螺纹(新工人(syobj,5),“螺纹5”);
t1.start();
t2.start();
t3.start();
t4.开始();
t5.开始();
}
HashMap lock_map=新建HashMap();
无效打印(INTA)引发中断异常{
已同步(锁定映射){
整数lock=lock\u map.get(a);
if(lock!=null){
已同步(锁定){
System.out.println(Thread.currentThread().getName()+“正在等待”);
lock_map.notify();
lock.wait();
}
}否则{
lock_map.put(a,新整数(a));
系统输出打印项次(a);
}
}
}
}
类工作者实现可运行的{
int-val;
同步打印对象;
公共工作者(同步打印对象,int v){
这个。val=v;
this.obj=obj;
}
公开募捐{
试一试{
对象打印(val);
}捕获(中断异常e){}
}
}

您可以用一个。更改
lock\u映射。将
放入
lock\u映射。putIfAbsent
您的
等待
不在循环内。请参阅,了解这会产生问题的原因

我不明白这与问题有什么关系,你能详细说明一下吗?@Arian Hosseinzadeh我不太清楚你对
lock\u map
的锁定在做什么,但是如果它是为了防止多个线程同时调用
lock\u map.put
,那么您可以使用
ConcurrentHashMap#putIfAbsent
来实现这一点-如果两个线程同时调用
putIfAbsent
,那么只有一个线程会成功。