0 java multithreading locking wait
我有一个java多线程问题.我有两个线程访问一个方法A(),它在内部有一个for循环,在循环中调用一个方法B().应使用线程名锁定锁定方法A,并且应将方法B锁定在方法B操作的对象ID上.检查以下代码.
Currrent代码
private static final ConcurrentHashMap<Object, Object> LOCKS = new ConcurrentHashMap<Object, Object>();
private void methodA(){
LOCKS.putIfAbsent(Thread.currentThread().getName(), new Object()))
synchronized (LOCKS.putIfAbsent(Thread.currentThread().getName(), new Object())) {
for(loop through all objects) {
methodB(Object1);
}
}
}
private void methodB(Object1 object1) {
LOCKS.putIfAbsent(object1.getObjectId(), new Object()))
synchronized(LOCKS.putIfAbsent(object1.getObjectId(), new Object())){
//<Work on object1>
}
}
Run Code Online (Sandbox Code Playgroud)
我已经完成了上面的代码,以确保2个不同的线程应该能够并行访问methodA(),但不应该在methodB()中一次使用同一个Object1(由methodA()调用).即; 虽然我希望线程A和线程B同时访问methodA(),然后循环遍历'for'循环中的所有对象并通过调用methodB()对每个对象进行操作,我不希望线程A和B到一次作用于SAME对象实例.因此上面的代码基于对象实例ID锁定methodB().
需要改进.
在上面的代码中,如果线程A和线程B来到methodB()并发现它们都想要在同一个对象'obj1'上工作,那么现在使用上面的代码,线程A将等待,或者线程B将等待另一个一个完成取决于谁到达并锁定methodB()首先.
但想象一下,线程A首先获得锁定并执行methodB()需要9个小时才能完成处理'obj1'.在这种情况下,线程B需要等待整整9个小时才有机会执行methodB(),从而处理'obj1'.
我不希望这种情况发生.线程B,一旦发现方法B()被线程A锁定在'obj1'的名称中,就应该继续(稍后再回到obj1)来尝试锁定和处理其他对象.即; 它应该尝试处理'for'循环中的其他对象,如对象列表中的obj1,obj2等.
任何解决这个"无需等待锁定"问题的输入将不胜感激.
非常感谢您的帮助.
一些澄清,以改善答案.
你能做的最好的事情就是保持简单.
应使用线程名锁定锁定方法A.
只有锁定共享对象才有意义.锁定线程本地锁是没有意义的.
synchronized(LOCKS.putIfAbsent(object1.getObjectId(),new Object()))
这将返回null并在第一次运行时抛出NullPointerException.
我会替换代码
private void methodA(){
List<Object1> objects = new ArrayList<>(this.objectList);
while(true) {
for(Iterator<Object1> iter = objects.iterator() : objects)
if(object1.methodB())
iter.remove();
if(objects.isEmpty()) break;
Thread.sleep(WAIT_TIME_BEFORE_TRYING_AGAIN);
}
}
// in class for Object1
final Lock lock = new ReentrantLock();
public boolean methodB() {
if (!lock.tryLock())
return false;
try {
// work on this
return true;
} finally {
lock.unlock();
}
}
Run Code Online (Sandbox Code Playgroud)
根据您想要处理无法锁定的对象的方式,您可以将它们添加到后台ExecutorService.您可以让methodA重复调用此失败的所有剩余对象.
理想情况下,您会找到一种方法来最小化锁定的时间,甚至完全不需要锁定.例如,像AtomicReference和CopyOnWriteArrayList这样的类是线程安全且无锁的.
| 归档时间: |
|
| 查看次数: |
965 次 |
| 最近记录: |