【发布时间】:2020-08-23 13:29:04
【问题描述】:
例如,我试图了解 signalAll() 如何不破坏关键部分
//Some Class Here is Trying to use an resource which is to to initialized in an seperate thread
ReentrantLock lock=new ReentrantLock();
Condition wait=lock.newCondition();
Resource res=new Resource(lock); //An Important Resource Which Should Be Accessed Only By One Thread At A Time
void doStuff()
{
lock.lock();
try
{
if(!res.initialized.get()) //Check If Resource Was Previously Not Initialized
{
res.init();//Spawns An Seperate Thread For Initialization
wait.await();//If Resource Is Not Initialized Make Whatever Thread Which Reached This Point Wait
}
res.use(); //Here Is What I Don't Understand If Let's Say 5 threads were parked in the previous statement then when signalAll() is called won't all 5 threads wake up simultaneously and resume execution at this point and use this resource at the same time and break this resource? But it dosen't turn out like that why?
}
}
finally{lock.unlock();}
}
private static final class Resource extends Thread
{
private final ReentrantLock lock;
private final Condition init;
private final AtomicBoolean
started=new AtomicBoolean(false),
initialized=new AtomicBoolean(false);
private Resource(ReentrantLock lock)
{
this.lock=lock;
this.init=lock.newCondition();
}
private void init()
{
if(!initialized.get())
{
if(!started.get())
{
start();
started.set(true);
}
while(!initialized.get()){init.awaitUninterruptibly();}//In case of spurrous wakeups check repeatedlly
}
}
private void use(){}//Important Stuff
private int get(){return 5;}
@Override
public void run()
{
lock.lock();
try
{
TimeUnit.SECONDS.sleep(5);
initialized.set(true);
init.signalAll(); //This should in the above example wake up all 5 threads simultaneously and break the critical section but that does not happen how?
}
catch(InterruptedException ex){}
finally{lock.unlock();}
}
}
仅使用 signal() 只有一个线程唤醒并在关键部分恢复执行,所以没有中断,但是使用 signalAll() 多个线程在它被停放的点恢复执行[即在关键部分内],所以没有什么中断?以及我们应该在何时/何地使用每种方法,即最佳实践
【问题讨论】:
标签: java multithreading locking