2012-06-29 4 views
3

J'essaye d'écrire un programme qui vérifie la santé d'une base de données. L'un des éléments des éléments du programme est supposé être que le programme interroge une base de données et attend 5 minutes en utilisant wait. S'il n'y a pas de réponse, il notifie et envoie des emails. Ma connexion à la base de données/envoi de courriels fonctionne, mais j'ai du mal à mettre en place l'attente et à notifier. J'ai lu l'API et il est facile à comprendre dans un programme simple, mais je suis vraiment confus quant à la façon de l'implanter dans ce cas avec toutes les complications supplémentaires à cause d'erreurs où je ne peux pas appeler dynamique d'une méthode statique .Mise en œuvre Attendre et notifier

J'ai lu beaucoup de threads avec wait et notify, mais je n'ai pas compris comment le faire correctement dans mon programme. Si quelqu'un pouvait me donner quelques conseils, ce serait une aide énorme. Merci!

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); 
    } 
    } 
+0

C'est trop beaucoup de code. Faites bouillir le problème jusqu'aux bases avant de poster. Faire un SSCCE. – erickson

+0

hmm bien je suppose que je pourrais supprimer le code parce que rien de tout cela est vraiment pertinent à ce que je demande. J'essaie juste de comprendre comment faire et notifier où le thread 2 commence une requête, le thread 1 attend 5 minutes, si le thread 2 renvoie un résultat qu'il notifie, sinon le thread 1 fait une tâche différente. Le problème pour moi est que dans tous les exemples d'attente et de notification, les threads utilisent une méthode d'exécution et font la même chose – Lemonio

Répondre

1

Planifiez une tâche avec un ExecutorService qui envoie un courrier électronique. Lorsque vous obtenez une réponse, annulez la tâche. Si cela fait plus de 5 minutes, le courrier a déjà été envoyé par le thread exécuteur, et l'annulation est un no-op. Sinon, l'e-mail est abandonné.


Ce n'est pas même un problème wait()/notify(); il n'y a pas de données qui passent entre les threads. Voici un bas niveau équivalent à la solution 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(); 
} 
+0

hmm cela semble être une très bonne idée. Je voudrais utiliser attendre et notifier cependant parce que mon directeur a spécifiquement dit qu'il voulait attendre et notifier. En outre, je pense que ce que je suis confus est que dans les exemples les threads font toujours la même chose, comme les deux compte à rebours, mais j'ai besoin des threads pour faire deux choses très différentes avec des méthodes différentes les contrôlant. – Lemonio

+0

lol je suis un stagiaire donc je suis totalement bien avec ça – Lemonio

1

Si attente et de notification doit être utilisé, je vous conseille d'utiliser l'interface de verrouillage et Reentrant verrouillage classe de java.util.concurrent package...

Questions connexes