2

以前、待機と通知の実装に関する問題を投稿しましたが、あまり明確ではなかったので、ここでより具体的な質問をします。

以下の長いコードブロックには、1つの待機と1つの通知があります。通知は待機を停止し、待機を停止することになっています。現時点では、待機は機能すると思いますが、通知は機能しません。通知が待機を通知しない理由を誰かが説明できますか?ありがとう!

注:残りのコードは機能しますが、私はこれら2つの特定の部分にのみ関心があります。

import com.fmr.ipgt.email.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import javax.mail.MessagingException;

class MyQuery {
synchronized void qQuery() throws Exception {
    String query = ".z.k"; // The query that is used to query q; this can be changed here.
    int version = 0;
    c qConn = null;
    qConn = new c(Main.host,Main.port); // Connect to the q database
      while (Main.healthy) {
          Object o = qConn.k(query); // Query q
          version = c.t(o);
          if(!(version==0)) {
              System.out.println(version);
              System.out.println("database healthy");
              NewThread.suspendFlag = false;
              notify(); 
              break; // End the process if the database responds
          }
          }

       System.out.println("reaches loop end");
  }
}

class MyThread implements Runnable {
  MyQuery myResource;

  MyThread(String name, MyQuery so) {
    myResource = so;
    new Thread(this, name).start();
  }

  public void run() {

    try {
      myResource.qQuery(); // Begin a method to query q.
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

class NewThread implements Runnable {
       String name; // name of thread
       Thread t;
       static boolean suspendFlag;
    private int minutes;
       NewThread(int minutes) {
           this.minutes = minutes;
           System.out.println("reaches constructor");
          t = new Thread(this);
          suspendFlag = true;
          t.start(); // Start the thread
       }
       // This is the entry point for thread.
       public void run() {
          try {
             synchronized(this) {
                while(suspendFlag) {

                   System.out.println("reaches wait");
                   wait(minutes*60000);

                   System.out.println("reaches end");
                   if(suspendFlag) {
                       Main.setHealth(false);
                    Main.sendMessages(); // The database has not responded for the given time. Report that it is unhealthy.
                   }
                   break;
                }
              }
          } catch (InterruptedException e) {
             System.out.println(name + " interrupted.");
          } catch (MessagingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
       }
    }

public class Main {

private static String[] recipients;
private static String subject = "Database Failure";
private static String message = "The database has failed or is in a hung state";
private static String from;
static String host;
static int port;
private static String emails;
private static int minutes;
static boolean healthy = true;
public static void main(String args[]) throws Exception {

    // Import information from the configuration file
      SAXBuilder builder = new SAXBuilder();
      File xmlFile = new File("/export/home/rhadm/file.xml"); // Note: The directory for the configuration file may need to be changed

      try {

        Document document = (Document) builder.build(xmlFile);
        Element rootNode = document.getRootElement();
        List list = rootNode.getChildren("parameters");
           Element node = (Element) list.get(0);

          host = node.getChildText("host");
           port = Integer.parseInt(node.getChildText("port"));
           emails = node.getChildText("emails");
           String delims = "[ ]+";
           recipients = emails.split(delims); // parse email list
           minutes = Integer.parseInt(node.getChildText("time"));
           from = node.getChildText("from");

      } catch (IOException io) {
        System.out.println(io.getMessage());
      } catch (JDOMException jdomex) {
        System.out.println(jdomex.getMessage());
      }
    MyQuery unhealthy = new MyQuery();
    NewThread ob1 = new NewThread(minutes);
    new MyThread("MyThread", unhealthy);  // Create new Thread


  }
  public static void setHealth(boolean health){
      System.out.println("database unhealthy");
    healthy  = health;  
  }

  public static void sendMessages() throws MessagingException {
        System.out.println("sending emails");
      FCAPMailSender.postMail(recipients,subject,message,from);
  }
  }
4

1 に答える 1

0

異なるオブジェクトで同期しています。通知は、同期されたオブジェクトにのみ影響します-同じオブジェクトとインスタンスで待機しています。

待機中のスレッドは同期されNewThread、通知スレッドがMyQueryインスタンスで同期している間待機します

共有オブジェクトがあります。

private final Object LOCK = new Object();
synchronized(LOCK){
  LOCK.wait();
}
synchronized(LOCK){
  LOCK.notify();
}
于 2012-06-29T20:07:05.627 に答える