如何将连接信息传递给runnable?

时间:2012-04-15 16:27:43

标签: java multithreading

我在将一些连接信息传递给可运行的线程时遇到问题(使用rabbitmq,但我认为这不是特定于rabbitmq并且可以应用于任何东西)。我的目标是让一些工作线程从队列中处理一些工作,但我不希望每次都打开和关闭连接的开销。

代码在没有runnable的情况下工作(它实际上是从rabbitmq教程中窃取的)但是一旦我实现了runnable传递连接,我就在doWork()上得到了这个错误: The method doWork(Channel, String) is undefined for the type Worker如果我从runnable中删除Channel并且不发送它,那么程序工作正常但是没有传递连接信息。我该怎么办?

这是我的代码:

      //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() {

3 个答案:

答案 0 :(得分:4)

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

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

但是您可能希望将所有这些移动到外部线程,这可以通过以下方式完成:

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

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

答案 1 :(得分:3)

您正在尝试调用名为doWork的方法:

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

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

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

但你更有可能试图在那里分叉一个线程,所以它会是:

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

顺便说一句,你应该将你的班级名称大写,以便更容易看到。 doWork应该重命名为DoWork,然后更容易看到方法名称和类名称之间的区别。方法名称应始终以小写字母开头。

答案 2 :(得分:1)

Worker课程的某个地方,您定义了doWork(String message)方法。在doWork类(其名称不遵循Java约定,btw)中定义的内容无关紧要,除非您创建了该类的实例并在该实例上调用该方法;你正试图调用Worker类的方法。