The idea behind the inner-loop is to update the model more than once if the game is lagging behind. Meaning, on slower computers, it will occationally skip drawing one or more frames.
[edit] Note, this means that you need to separate out your rendering code from the code that updates the model. Unfortunately, that often means extra loops. For instance, to update the position of all the sprites in the game, you’ll need to iterate over the collection of sprite positions. Then later when you draw the sprites, you’ll need to iterate over that collection again to access those sprite positions. You could kill 2 birds at the same time and do the position updates and drawing within the same loop, but you’ll never be able to skip frames if you do that.
[edit] Also, this design assumes that it takes a lot less time to update the model than it does to render the frame to the screen. The inner-loop can be modified to put a cap on the number of times the model can be updated per rendering. Meaning, you can set the max number of frames to ever skip. That way for computationally complex games it may occationally slow down (lag behind), but at least it won’t be skipping so many frames that the screen effectively keeps freezing, making the game unplayable.
Thread.sleep() is more accurate than you think at least under windows. You can measure the sleep time using System.nanoTime(). I found it often sleeps about 0.1 extra milliseconds than specified. But, that still doesn’t matter. If it sleep too long on one iteration, it will sleep less the successive iteration.