2012-04-15 7 views
1

Ich habe Probleme beim Übergeben einiger Verbindungsinformationen an einen ausführbaren Thread (unter Verwendung von rabbitmq, aber ich denke nicht, dass dies spezifisch für rabbitmq ist und sich auf alles anwenden lässt). Mein Ziel ist es, ein paar Worker-Threads zu haben, die einige Arbeiten aus einer Warteschlange verarbeiten, aber ich möchte nicht, dass jedes Mal Verbindungen geöffnet und geschlossen werden.Wie kann ich Verbindungsinformationen an eine ausführbare Datei übergeben?

Der Code funktioniert ohne runnable (es ist eigentlich aus den rabbitmq Tutorials gestohlen), aber sobald ich ein lauffähiges implementieren eine Verbindung geben ich auf doWork diesen Fehler(): The method doWork(Channel, String) is undefined for the type Worker Wenn ich entfernen Kanal von runnable und nicht Senden Sie es dann das Programm funktioniert gut, aber die Verbindungsinformationen werden nicht übergeben. Was kann ich tun?

Hier ist mein Code:

 //this is the standard stuff to start a connection 
ConnectionFactory factory = new ConnectionFactory(); 
      factory.setHost("localhost"); 
      Connection connection = factory.newConnection(); 
      Channel channel = connection.createChannel(); 

     System.out.println(" [*] Waiting for messages. To exit press CTRL+C"); 

     channel.basicQos(1); 

     QueueingConsumer consumer = new QueueingConsumer(channel); 
     channel.basicConsume("task_queue", false, consumer); 
     //end of standard stuff  

     while (true) { 
      QueueingConsumer.Delivery delivery = consumer.nextDelivery(); 
      String message = new String(delivery.getBody()); 

      System.out.println(" [x] Received '" + message + "'"); 
      doWork(channel, message); 
      System.out.println(" [x] Done"); 

      channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false); 
     } 
     } 

dann:

public class doWork implements Runnable{ 

     protected Channel channel = null; 
     protected String message = null; 

     public doWork(Channel channel, String message) { 
      this.channel = channel; 
      this.message = message; 
     } 


     public void run() { 
+2

Benennen Sie Ihre Klassen in 'UpperCase', Methoden und Felder in' camelCase' und statische Endkonstanten in 'FULL_CAPS'. Beachten Sie auch, dass [Interfaces immer Adjektive und Klassen Substantive sind] (http://www.iwombat.com/standards/JavaStyleGuide.html#Class%20and%20Interface%20Names). – adarshr

Antwort

4

Wenn Sie Ihren Code in eine ausführbare Datei verschoben haben, bedeutet dies, dass Sie eine neue Klasse erstellt haben. Wenn Sie es aufrufen möchten, dann sollten Sie so etwas wie dieses

doWork work = new doWork(channel, message); 
work.run(); 

haben, aber Sie wollen wahrscheinlich alles, was zu einem Außengewinde zu bewegen, die von getan wird: Btw

Thread t = new Thread(new doWork(channel, message)); 
t.start(); 

, Klassen sollten Beginnen Sie mit einem Großbuchstaben, dadurch wird der Code deutlich lesbarer.

+0

Vielen Dank, ich werde mein Gehäuse anpassen. Habe ich einen Fehler, wenn ich jedes Mal einen neuen Thread starte, wenn ich ihn auswähle? Was passiert, wenn ich (in meinem Queue-Beispiel) nur 4 (Anzahl von Kernen, die ich habe) Elemente gleichzeitig verarbeiten möchte? Ich kann es auf dem Warteschlangenserver einstellen, aber es wird es für alle meine Clients tun (sogar für solche mit mehr Kernen). Gibt es eine Möglichkeit, die Anzahl der von mir gestarteten Threads auf eine bestimmte Anzahl zu beschränken? –

+2

Wenn Sie die Anzahl der Threads begrenzen wollen, sollten Sie sich 'Executors.newFixedThreadPool (num)' anschauen.Sie reichen nur Jobs ein und der Pool kümmert sich darum, die Threads auf dem richtigen Level zu halten. – Gray

3

Sie versuchen, eine Methode doWork Namen zu nennen:

// this is a method call 
doWork(channel, message); 

Was Sie tun wollen (ich glaube) ist etwas wie:

aber wahrscheinlicher Sie versuchen, einen Thread gibt Gabel soll es so sein würde:

new Thread(new doWork(channel, message)).start(); 

Als Nebenwirkung, sollten Sie Ihre Klassennamen nutzen, die es leichter zu sehen wäre. doWork sollte in DoWork umbenannt werden, dann ist es einfacher, den Unterschied zwischen Methodennamen und Klassennamen zu sehen. Methodennamen sollten immer mit einem Kleinbuchstaben beginnen.

1

Irgendwo in Ihrer Worker Klasse haben Sie eine Methode doWork(String message) definiert. Was innerhalb Ihrer Klasse doWork definiert ist (dessen Name nicht den Java-Konventionen folgt, btw), spielt keine Rolle, bis Sie eine Instanz dieser Klasse erstellt und die Methode für diese Instanz aufgerufen haben. Sie versuchen derzeit, eine Methode der Klasse Worker aufzurufen.

Verwandte Themen