title: Implementing shared resource algo with singleton and multithreading
body: <p>I am trying implementing something like-
    A singleton class hold some objects of type thread (classroom with 2 student objects) and there exists a class which holds some static resource(Resource.java). I start the 2 threads in my singleton class one after the other and make them to consume the static resource. This takes place in a synchronized method of the class which has resources. In the run method of the thread, i call the above-synchronized method and get output as below-</p>
  
  <p><strong>output-</strong><br/></p>
  
  <p>Request for chocolate from : 0 <br/>
  check if other childs available: Yes<br/>
  block ends<br/>
  --Student 0 finishes run!---<br/> 
  Request for chocolate from : 1<br/>
  check if other childs available: Yes<br/>
  block ends<br/>
  --Student 1 finishes run!---   </p>
  
  <p>My question is that after child_1 finishes execution of the synchronized block and executes sleep(), (thread_1 sleeps for 5 sec and thread_2 for 0 sec) the other thread (child_2) should start the execution of the synchronized block before child_1 wakes up because the child_1 is not in the synchronized block and sleep time of child_1 > then the execution time of child_2. WHy is child_1 blocking the other?</p>
  
  <p><strong>expected output-</strong><br/>
  Request for chocolate from : 0<br/>
  check if other childs available: Yes<br/>
  block ends<br/>
  Request for chocolate from : 1<br/>
  check if other childs available: Yes<br/>
  block ends<br/>
  --Student 1 finishes run!--- <br/>
  <strong>--Student 0 finishes run!---</strong> </p>
  
  <p>How do i accomplish this.</p>
  
  <p>My code file--
  Singleton class (ClassRoom.java)</p>
  
  <pre><code>public class ClassRoom {
  
  private static ClassRoom instance = null;
  private static Student s[];
  
  public static ClassRoom getInstance() {
      if (instance == null) {
          instance = new ClassRoom();
          initStudents();
      }
      return instance;
  }
  
  private static void initStudents() {
      s= new Student[2];
      s[0] = new Student(0,2,5);
      s[1] = new Student(1,2,5);
  }
  
  public Student getStudent(int i) {
      return s[i];
  }
  }
  </code></pre>
  
  <p>Student.java</p>
  
  <pre><code>public class Student extends Thread {
  int sid;
  int max_choco;
  int allo_choco;
  private Resource resource= new Resource();
  
  public Student(int i, int j , int k) {
      sid = i;
      allo_choco = j;
      max_choco = k;
  }
  
  @Override
  public void run() {
      try {
          resource.requestChocolate(sid, 2);
          Thread.sleep(Math.abs(1-sid)*5000);
          System.out.println("--Student "+sid+" finishes run!--- ");
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
  }
  public int getSid() { return sid;}
  
  @Override
  public String toString() {
      return sid+" : "+allo_choco+" : "+max_choco;
  }
  }
  </code></pre>
  
  <p>Resource.java</p>
  
  <pre><code>public class Resource {
  
  private static int total_chocolate = 10;
  
  public void requestChocolate(int id, int request) {
      synchronized (Student.class) {
          System.out.println("Request for chocolate from : "+ 
                             ClassRoom.getInstance().getStudent(id).getSid());
          if(request &lt;= total_chocolate) {
              System.out.println("check if other childs available: "
              +((ClassRoom.getInstance().getStudent((id+1)%2).getSid()&gt;-1 
              &amp;&amp; ClassRoom.getInstance().getStudent((id+1)%2).getSid()&lt;3)?"Yes":"No")); {
              }
              total_chocolate-=request;
          System.out.println("block ends");
          } else {
              System.out.println("Request cannot be granted");
          }
      }
  }
  }
  </code></pre>
  
  <p>Runner class(Test.java)</p>
  
  <pre><code>public class Test {
  
   public static void main(String args[]) {
       ClassRoom room = ClassRoom.getInstance();
       for(int i = 0 ; i&lt; 2; i++) {
           room.getStudent(i).run();
       }
   }
   }
  </code></pre>