这是超人生活中的黑暗时期。 乔尔·艾尔(Jor-El)希望他继续航行,为他的最终命运做好准备。 然而,地球面临着世界末日,正义联盟需要他们的钢铁侠行动来拯救世界。 但是由于我们只有一个超人,您不能同时做这两个事情。 同样,他不能在没有首先实现自己的命运并实现其真正力量的情况下与世界末日作战。 我们该如何呼吁超人,而不是让该人为之烦恼。 这应该以一种有序的方式进行,其中必须等到航程完成。 我们将利用Java Monitors帮助SuperMan聆听他的K星之父,并及时回来拯救世界免遭厄运。 首先,我们定义钢铁侠。
/**
* 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();
}
}
因此,我们定义了超人。 请注意,他定义了两种方法。 一个允许他继续航行,另一个允许他从当前航行回叫。 如您所见,超人不会处理异常,因为……。 他是超人 ,他是 例外 。 您可以看到,在每次调用之前,我们检查指示他是否在航行中的布尔值,并根据所调用的方法,调用Object的wait()来暂停正在调用该方法的当前线程,直到通知()由当前在对象上运行的线程调用。 请注意,应在同步方法或块内调用wait()和notify(),以使其正常工作。 因为您首先需要获取锁才能停止或通知它。
回到上一期,我们知道正义联盟和Jor-El都需要超人,但出于不同的目的。 让我们看一下下面的代码片段如何使这场战斗展开。
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希望回电超人以拯救世界。 但是幸运的是他还没有航行,所以要求他返回是违法的。 然后乔勒(JorEl)要求儿子继续航行,以实现自己的真实命运。 只有在这次航行之后,他才能返回以拯救地球。 如果现在运行此命令,则可以看到JusticeLeague线程已暂停,直到超人继续航行并调用notify为止。 只是为了好玩,尝试注释掉notify()方法,您将看到应用程序挂起,因为现在一个线程将无限期等待,直到通知该过程完成为止。
如果不是对于Java Monitors,SuperMan将会失败,因为他将不得不面对世界末日而没有先行航行并实现自己的命运。 Java再次拯救了世界。 注意:这个故事是虚构的,但Java Monitors是真实的
翻译自: https://www.javacodegeeks.com/2013/04/superman-bound-by-java-monitors.html