2012-04-10 5 views
0

Ich habe eine Web-Crawler, wo das Grundlayout ein Manager ist, die Agenten, die offene Verbindung ausgeführt wird, um den Inhalt holen und sie in einer Datenbank einzufügen.Laufende Agenten in "unendlichen" Schleife Threads ist falsch?

Jede dieser Agenten ausgeführt werden in einem eigenen Thread in einer Schleife, bis der Benutzer ein Stoppsignal senden. Diese Agenten erhalten die Aufgaben vom Manager-Agenten.

Das Problem ist, wenn eine Ausnahme in einem Mittel erfolgt, kann sie nicht an die Schnittstelle throwed wird (es sei denn, ich einige Beobachter verwenden, um zu signalisieren, dass eine Ausnahme aufgetreten ist).

Ich denke, dass dieses Design falsch ist und die richtige ist eine endliche Aufgabe erstellen und setzen sie in den Executor (erstellen Sie eine Aufgabe für jede URL zu öffnen Verbindung, Inhalte abrufen oder in die Datenbank einfügen).

Ich bin richtig, dass mein aktuelles Design ist falsch und muss das Layout ändern? Was ist das richtige Layout für die Verwendung von Multi-Threading, wenn verschiedene Agenten unterschiedliche Teile des Jobs ausführen?

Antwort

4

Ja, ich glaube, Sie sollten die Executors werden. Wenn Sie Callable Klassen einreichen, können Sie von Ihrer Spinne Agenten werfen und die zurück Future untersuchen, die die Ausnahme verursacht an den Auftraggeber geworfen werden, so kann es zu einem UI angemeldet oder angezeigt werden.

ExecutorService pool = Executors.newFixedThreadPool(10); 
Future<Void> future = pool.submit(new Callable<Void>() { 
    public Void call() throws Exception { 
     // your agent code goes here 
     // this can throw an exception in this block which will be re-thrown below 
     return null; 
    } 
}); 
... 
try { 
    // then the exception will be thrown here for you to catch and log 
    future.get(); 
} catch (ExecutionException e) { 
    // log the e.getCause() here 
} 
... 
pool.shutdown(); 
+0

Angenommen, diese Klasse ist der Manager, ich habe drei Arten von Agenten parallel ausgeführt. Die Aufgaben werden nacheinander ausgeführt (Öffnen, Abrufen und Einfügen, jeweils ein Agent). Ich brauche eine Schleife im Manager, um die Ergebnisse jedes Executors zu erhalten. Aber die Ausführung wird blockiert, wenn die 'get()' Methode aufgerufen wird, also brauche ich drei Manager, von denen jeder für die Ausführung eines Executors zur Ausführung nicht blockiert wird, während die get Methode aufgerufen wird. –

+0

Gibt es einen Grund, nicht alle 3 Agenten aus einem einzigen Thread @Renato aufzurufen? Gibt es einen Grund, jedem Agententyp einen Thread zu geben? Da sie jeweils einen Teil der gesamten Aufgabe ausführen, erscheint dies als unnötige Komplexität. – Gray

+0

Der Grund ist, dass offene Verbindungen zu Standorten langsam sind (I/O), also habe ich 10 Threads offene Verbindungen parallel (Beispiel). Das Abrufen des Inhalts ist schneller, wenn die Verbindung bereits geöffnet ist, daher habe ich nur 2 Abrufvorgänge für 10 Öffner. Wenn die Öffner holen, öffnen sie keine Verbindung und verlangsamen das Kriechen. Und der Inserter ist nur ein Thread, weil er die schnellste Operation ist und auf diese Weise nur eine Datenbankverbindung verwendet. Wenn Öffner oder Abrufer in die Datenbank eingefügt werden, muss jeweils eine Datenbankverbindung geöffnet werden. –

Verwandte Themen