private boolean safeCheck() {
    boolean finish[] = new boolean[Banker.NumThreads];
    int work[] = new int[Banker.NumRes]; //make copy of Avail
    for (int i = 0; i < Banker.NumRes; i++)  work[i] = avail[i];

    boolean changed = true;
    while (changed == true) {
      changed = false;
      for ( j = 0; j < Banker.NumThreads; j++) {
        if (true == finish[j]) continue;

        boolean canFinish = true; // true if (need[] <= Work[])
        for (int i = 0; i < Banker.NumRes; i++)
          if (need[j][i] > work[i]) canFinish = false;

        if (canFinish) {
          finish[j] = true; //flag thread as finished

          for (int i = 0; i < Banker.NumRes; i++)
            work[i] += Alloc[j][i]; // add its alloc into work;
          changed = true;
        }
      } //for each thread

      boolean done = true; //check if all threads have finished
      for (int j = 0; j < Banker.NumThreads; j++)
        if (! (finish[j])) done = false;

      if (done) return true;
    } //while (changed)

    return false; //not all can finish, therefore unsafe
 }