Я хочу иметь объект с методом, который только печатает числа, которые еще не были получены, поэтому я использовал следующий код. Идея состоит в том, что я использую карту, которая для каждого целого хранит блокировку, поток ожидает блокировку, если она уже находится на карте, иначе она поместит новую блокировку в карту с этим целым как ключ и объект 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) {}
}
}
Я не понимаю, как это связано с проблемой, можете ли вы подробно рассказать? –
@Arian Hosseinzadeh Я не совсем понимаю, что делает ваша блокировка на 'lock_map', но если это так, чтобы предотвратить одновременное одновременное вызов нескольких вызовов из' lock_map.put', вы можете использовать 'ConcurrentHashMap # putIfAbsent' для выполните это вместо этого - если два потока вызовут 'putIfAbsent' в то же время, то только один будет успешным. –