Код:
//подключаем библиотеки
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
//Producer 
class Producer implements Runnable{
   Lock lock;
   Lock lockN;
   Lock lock0;
   
   Producer(Lock lock, Lock lockN, Lock lock0){
      this.lock = lock;
      this.lockN = lockN;
      this.lock0 = lock0;
   }
   
   public void produce(int ii){
      //пытаемся блокировать lock 
      lock.lock();
      try{   
         System.out.println("Producer iteration");
         while(Threads.s == Threads.N){
            lock.unlock();
            lock.lock();
         }
            Threads.s += 1;
         System.out.println(Threads.s+" "+ii);
      }
      finally{
         lock.unlock();
      }
   }
   //секция выполнения 
   public void run(){
      for(int i = 0; i < 10; i++){
         produce(i);
      }
   }
}
class Consumer implements Runnable{
   Lock lock;
   Lock lockN;
   Lock lock0;
   Consumer(Lock lock, Lock lockN, Lock lock0){
      this.lock = lock;
      this.lock0 = lock0;
      this.lockN = lockN;
   }
   public void consume(int ii){
      lock.lock();
      try{
         System.out.println("Consumer iteration");
         while(Threads.s==0){
            lock.unlock();
            lock.lock();
         }
            Threads.s -= 1;
         System.out.println(Threads.s+" "+ii);
      }
      finally{
         lock.unlock();
      }
   }
   public void run(){
      for(int i = 0; i < 10; i++){
         consume(i);
      }
   }
}
public class Threads{
   public static int s;
   public static int N;
   public static void main(String Args[]){
      s = 0;
      N = 4;
      //запускаем произвольное кол-во thredo'в 
      ExecutorService exec = Executors.newCachedThreadPool();
      Lock lock = new ReentrantLock();
      Lock lockN = new ReentrantLock();
      Lock lock0 = new ReentrantLock();
      
      exec.submit(new Producer(lock, lockN, lock0));
      exec.submit(new Consumer(lock, lockN, lock0));
      //закрываем thread'ы;
      exec.shutdown();
   }
}
/* Producer увеличивает значение счётчика Threads.s  на 1 , как только счётчик = 4 ==> останавливается. */
Если запустить программу без lockN, lock0 - выводит 
Цитата:
producer iteration
consumer iteration
 и зависает.
Вопрос : зачем в программе нужны lockN  и lock0 ?