2

データベースの状態をチェックするプログラムを作成しようとしています。プログラムの要素の 1 つは、プログラムがデータベースにクエリを実行し、wait を使用して 5 分間待機することです。応答がない場合は、通知していくつかのメールを送信します。データベースへの接続/メールの送信はすべて機能しますが、待機と通知の実装に問題があります。私はAPIを読み、単純なプログラムで理解しやすいですが、静的メソッドから動的なものを呼び出すことができないというエラーのために、この場合にすべての追加の複雑さでそれを実装する方法について本当に混乱しています.

私は待機と通知を使用して多くのスレッドを読んでいますが、プログラムで正しく行う方法がわかりません。誰かが私にいくつかのヒントを与えることができれば、それは大きな助けになるでしょう. ありがとう!

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 MyResource {
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)) {
              break; // End the process if the database responds
          }
          }
  }
  synchronized void start() throws Exception {
    Main.setHealth(false);
    Main.sendMessages();
  }
}

class MyThread implements Runnable {
  MyResource myResource;

  MyThread(String name, MyResource 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();
    }
  }
}

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/jflt/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());
      }
    MyResource unhealthy = new MyResource();
    new MyThread("MyThread", unhealthy);  // Create new Thread
    new MyThread("WaitThread", unhealthy);
    while(healthy) {
    Thread.sleep(minutes*60000); // The wrong thread is sleeping here. The main method should probably be a different thread instead which will then need to wait and the second thread will notify.
    }
    unhealthy.start(); // The database has not responded for the given time. Report that it is unhealthy.
  }
  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

2 に答える 2

0

ExecutorServiceメールを送信するタスクをスケジュールします。応答があったら、タスクをキャンセルします。5分以上経過している場合、メールはすでにエグゼキュータスレッドによって送信されており、キャンセルは無効です。それ以外の場合、電子メールは中止されます。


これはwait()/のnotify()問題でもありません。スレッド間でデータが渡されることはありません。ExecutorServiceこれがソリューションに相当する低レベルです。

void test() {
  Thread t = new Thread() {
    @Override
    public void run() {
      try { Thread.sleep(TimeUnit.MINUTES.toMillis(5)); } 
      catch(InterruptedException abort) { return; }
      email();
    }
  }
  t.start();
  query();
  t.interrupt();
}
于 2012-06-29T17:21:27.823 に答える
0

待機と通知を使用する場合は、 Lock InterfaceReentrant Lock Classを使用することをお勧めします。java.util.concurrent package...

于 2012-06-29T17:37:18.650 に答える