Статьи

SuperMan связан Java-мониторами

Темное время в жизни Супермена. Джор-Эл хочет, чтобы он отправился в путешествие, чтобы подготовить его к окончательной судьбе. И все же Земля столкнулась с судьбоносным днем, и Лига Справедливости нуждается в их Человеке из стали в действии, чтобы спасти мир. Но вы не можете сделать оба одновременно, так как у нас есть только один Супермен. Также он не может бороться с судьбоносным днем, не выполнив сначала свою судьбу и не осознав свои истинные силы. Как мы призываем Супермена, не заставляя человека сходить с ума от того, что делать. Это должно быть сделано упорядоченным образом, когда нужно ждать, пока путешествие не будет сделано. Мы будем использовать Java-мониторы, чтобы помочь SuperMan выслушать его отца-криптонца, а также вернуться вовремя, чтобы спасти мир от гибели. Прежде всего, мы определяем человека из стали;

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
 * The awesome kryptonian man is represented by this class
 *
 * @author Dinuka Arseculeratne
 *
 */
public class SuperMan {
 
 private boolean onVoyage = false;
 
 /**
  * Schedule a voyage for Superman. Note that this method first checks whether he is
  * already on a voyage, and if so calls the wait() method to hault the current thread
  * until notify is called and onVoyage is set to false.
  */
 public synchronized void goOnVoyage() {
 
  if (onVoyage) {
   try {
    System.out.println("SuperMan is already on a voyage. Please wait until he returns from his quest.");
    wait();
    System.out.println("His goyage is over, time for him to go on a new voyage....");
   } catch (InterruptedException e) {
    System.out.println(" I am SuperMan, i do not handle these petty exceptions");
   }
 
  }
  onVoyage = true;
  notify();
 
 }
 
 /**
  * This method calls Superman back from his current voyage. Again the method
  * checks whether Super man is not already on a voyage. If so the current thread is
  * Halted until he is schedule to go on a voyage because he needs to be on a voyage
  * to be called back in the first place.
  */
 public synchronized void returnFromVoyage() {
 
  if (!onVoyage) {
   try {
    System.out.println("SuperMan is not yet on a voyage. Please Wait.");
    wait();
    System.out.println("Great he has gone on a voyage, time to call him back!!");
   } catch (InterruptedException e) {
    System.out.println(" I am SuperMan, i do not handle these petty exceptions");
   }
  }
  onVoyage = false;
  notify();
 }
}

Supergirl34_coffeegrin
Итак, мы определили SuperMan. Обратите внимание, что у него есть два определенных метода. Один, который позволяет ему отправиться в путешествие, а другой, чтобы перезвонить ему из его нынешнего путешествия. Как видите, SuperMan не обрабатывает исключения, потому что, ну ………. Он Супермен и он
исключение Вы можете видеть, что перед каждым вызовом мы проверяем логическое значение, указывающее, находится ли он в рейсе или нет, и в зависимости от вызванного метода вызывается wait () объекта, чтобы остановить текущий поток, вызывающий метод, до момента уведомления () вызывается потоком, который в данный момент работает с объектом. Обратите внимание, что wait () и notify () должны вызываться внутри синхронизированного метода или блока, чтобы он работал правильно. Потому что сначала вам нужно получить блокировку, чтобы остановить или уведомить ее.

Возвращаясь к предыдущему вопросу, мы знаем, что и Лига Справедливости, и Джор-Эл нуждаются в Супермене, но для разных целей. Давайте посмотрим, как эта битва разворачивается с помощью следующего фрагмента кода;

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class Test {
 
 public static void main(String[] args) {
  SuperMan superMan = new SuperMan();
 
  JusticeLeague justiceLeague = new JusticeLeague(superMan);
  justiceLeague.start();
 
  JorEl jorEl = new JorEl(superMan);
  jorEl.start();
 
 }
 
}
 
class JusticeLeague extends Thread{
 
 private SuperMan superMan = null;
 
 public JusticeLeague(SuperMan superMan)
 {
  this.superMan = superMan;
 }
 
 @Override
 public void run() {
  superMan.returnFromVoyage();
 }
}
 
class JorEl extends Thread{
 
 private SuperMan superMan = null;
 public JorEl(SuperMan superMan)
 {
  this.superMan = superMan;
 }
 
 @Override
 public void run() {
  superMan.goOnVoyage();
 }
 
}

Обратите внимание, что здесь у нас есть JorEl и JusticeLeagure, работающие в двух разных потоках, пытающихся получить доступ к SuperMan одновременно. Как вы можете видеть из нашего основного метода, JusticeLeague хочет перезвонить SuperMan, чтобы спасти мир. Но, к счастью, он еще не в плавании, поэтому незаконно просить его вернуться. Затем приходит Джорел с просьбой, чтобы его сын отправился в путешествие, чтобы исполнить свое истинное предназначение. Только после этого путешествия он может вернуться, чтобы спасти планету Земля. Если вы запустите это сейчас, вы увидите, что поток JusticeLeague остановлен, пока SuperMan не отправится в путешествие и не будет вызвано уведомление. Просто для удовольствия попробуйте закомментировать метод notify (), и вы увидите, что приложение зависнет, потому что теперь один поток будет ждать бесконечно, пока не получит уведомление о завершении процесса.

Если бы не Java-мониторы, SuperMan потерпел бы неудачу, поскольку он бы столкнулся с судным днем, не отправившись в путешествие и не выполнив свою судьбу. И Java снова спасает мир. Примечание: история вымышленная, но мониторы Java реальны

Ссылка: SuperMan связан Java Monitors от нашего партнера по JCG Динуки Арурилератне в блоге My Journey By IT .