有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java ReentrantLock条件SignalAll()如何工作?

例如,我试图理解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();}
  }
 }

使用just signal()时,只有一个线程被唤醒,并在关键部分恢复执行,因此没有任何中断,但使用signalAll()时,多个线程会在其停驻的位置(即在关键部分内)恢复执行,那么什么也不会中断?我们应该在何时/何地使用每种方法,即最佳实践


共 (0) 个答案