2012-04-15 21 views
1

我遇到了问题,将一些连接信息传递给可运行线程(使用rabbitmq,但我不认为这是针对rabbitmq并可应用于任何事情)。我的目标是让几个工作线程从队列中处理一些工作,但我不希望每次都打开和关闭连接。如何将连接信息传递给可运行?

的代码就开始运行,而不运行的(它实际上是从的RabbitMQ教程被盗),但我实现一个可运行的经过我得到的doWork()这个错误的连接: The method doWork(Channel, String) is undefined for the type Worker如果我从可运行删除通道和不发送它然后程序工作正常,但连接信息未被传递。我能做什么?

这里是我的代码:

 //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); 
     } 
     } 

则:

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

请在'UpperCase'中命名你的类,'camelCase'中的方法和字段以及'FULL_CAPS'中的静态最终常量。另请注意[接口总是形容词,类是名词](http://www.iwombat.com/standards/JavaStyleGuide.html#Class%20and%20Interface%20Names)。 – adarshr 2012-04-15 16:36:08

回答

4

如果您将代码移至Runnable,这意味着您创建了一个新类。如果你想调用它,那么你应该有这样的事情

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

但你可能想要移动所有外部线程,这是完成:

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

顺便说一句,类应以大写字母开头,它使代码更具可读性。

+0

非常感谢,我会调整我的外壳。我是否错误地认为这是每次选择它时都会启动一个新线程?如果(在我的队列示例中)我会只想同时处理4个(我有多少个核心)项目会发生什么?我可以将它设置在队列服务器上,但它会为我的所有客户端(即使是拥有更多内核的客户端)都这样做,是否有办法将我启动的线程数限制为特定的数量? – 2012-04-15 19:57:32

+2

如果你想限制线程的数量,那么你应该看看'Executors.newFixedThreadPool(num)'。您只需提交作业,池会保持线程处于正确的水平。 – Gray 2012-04-15 21:17:06

3

您试图调用名为doWork方法:

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

你想做的事(我猜)是什么是这样的:

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

但更可能你想fork一个线程有那么这将是:

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

顺便说一句,你应该利用你的类名这将使它更容易看到。 doWork应该重命名为DoWork,那么更容易看到方法名称和类名称之间的区别。方法名称应始终以小写字母开头。

1

在您的Worker类中的某处,您定义了一个方法doWork(String message)。在您的doWork类(其名称不遵循Java约定,btw)中定义的内容,直到您创建该类的实例并调用该实例的方法才是重要的;你正试图调用目前的Worker类的方法。