Засыпание
Первый тест в этой программе sleep( ):
///:Continuing
///////////// Blocking via sleep() ///////////
class Sleeper1 extends Blockable { public Sleeper1(Container c) { super(c); } public synchronized void run() { while(true) { i++; update(); try { sleep(1000); } catch(InterruptedException e) { System.err.println("Interrupted"); } } } }
class Sleeper2 extends Blockable { public Sleeper2(Container c) { super(c); } public void run() { while(true) { change(); try { sleep(1000); } catch(InterruptedException e) { System.err.println("Interrupted"); } } } public synchronized void change() { i++; update(); } } ///:Continued
В Sleeper1 весь метод run( ) объявлен как synchronized. Можно видеть, что ассоциированный с этим объектом Peeker весело выполняется до тех пор, пока вы не запустите процесс, после чего Peeker замораживается. Это одна из форм блокировки: поскольку Sleeper1.run() объявлен synchronized, а как только процесс запускается он всегда находиться внутри run(), то метод никогда не снимет блокировку объекта и Peeker блокирован.
Sleeper2 предоставляет решение сделав run() не-synchronized. Только метод change() объявлен как synchronized, что означает, что пока run() в sleep(), Peeker может получить доступ к необходимым ему synchronized методам, в данном случае read(). И в данном случае видно, что Peeker продолжает выполняться и после старта процесса Sleeper2.