无法为多线程写正确的文件?

时间:2011-11-24 08:09:04

标签: java multithreading log4j

我发布了问题:how to use log4j in Multithread using java?。我得到了回应我尝试了一个解决方案,使用这个解决方案,我为每个线程创建了不同的日志文件,但每个线程的包含将陷入困境。

WorkThread.java

package com.demo;


import com.arosys.customexception.KeyNotFoundException;
import com.arosys.doqeap.exception.NullObjectFoundException;
import com.arosys.doqeap.exception.ValueNotFoundException;
import com.arosys.doqeap.serviceconfiguration.ServiceConfiguration;
import com.arosys.logger.LoggerFactory;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import java.io.IOException;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;


class wokerThread implements Runnable 
{ 
    private Connection connection; 
    private String requestExchangeName = null;
    private String requestQueueName = null;
    private String requestRoutingKey = null;
    private boolean durable = true;
    private ServiceConfiguration serviceConfiguration = null;

     public wokerThread(ServiceConfiguration config, Connection conn) 
     {

      this.connection=conn; 
          this.serviceConfiguration=config;
     } 

    public void init() throws  KeyNotFoundException, NullObjectFoundException, com.arosys.doqeap.exception.KeyNotFoundException, ValueNotFoundException
    {

        if(connection == null)   throw new NullObjectFoundException("MQConnection object found NULL(First set this Object)");
        if(serviceConfiguration == null)   throw new NullObjectFoundException("ServiceConfiguration object found NULL(First set this Object)");
        requestExchangeName = serviceConfiguration.getValue("request.exchangename");
        requestQueueName =serviceConfiguration.getValue("request.queuename");
        requestRoutingKey = serviceConfiguration.getValue("request.routekeyname");


    }  // end of init()


    public void run()
    {


        Channel channel=null;
        QueueingConsumer consumer = null;
        QueueingConsumer.Delivery delivery = null;
        boolean noAck = false;
        String exchangeType = "direct";

          Logger logger1=LoggerFactory.getLogger(" com.demo.wokerThread","resources/log4j.xml");
          logger1.removeAllAppenders();
          FileAppender appender = null;
          PatternLayout layout = new PatternLayout();
          layout.setConversionPattern("%d{yyyy-MM-dd HH:mm:ss} %p %c{1}:%L - %m%n");
          try {

               appender = new FileAppender(layout,"logs\\worker"+Thread.currentThread().getName()+".log",true);
               logger1.addAppender(appender);
               logger1.setLevel((Level) Level.DEBUG);    
            } catch (IOException ex) {
              ex.printStackTrace();
            }


        logger1.info("Thread name-"+ Thread.currentThread().getName());
        logger1.info("Appender Name "+appender.getFile());

        Thread runThread = Thread.currentThread();


        try    // try 
        {          
                 channel = connection.createChannel();
                 channel.exchangeDeclare(requestExchangeName, exchangeType, durable);
                 channel.queueDeclare(requestQueueName, durable,false,false,null);
                 channel.basicQos(1);
                 channel.queueBind(requestQueueName, requestExchangeName, requestRoutingKey);
                 consumer = new QueueingConsumer(channel);
                 channel.basicConsume(requestQueueName, noAck, consumer);        
                 logger1.info(runThread.getName()+" :: Starting to listen to Request Queue. . . . . . . . . . . ."+runThread);
                    while(true)
                    {

                         delivery = consumer.nextDelivery();
                         logger1.info(runThread+" ::  Message picked up from Queue--"+delivery);
                         channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);

                    } // end of stop while loop

        }
                // end of try 1
        catch(Exception e){  logger1.error(e); } // catch 1        
    } // run
} 

ThreadDemo .java

package com.demo;

import com.arosys.doqeap.exception.DatabaseException;
import com.arosys.doqeap.exception.FileNotFoundException;
import com.arosys.doqeap.exception.KeyNotFoundException;
import com.arosys.doqeap.exception.MQConnectionNotEstablished;
import com.arosys.doqeap.exception.NullObjectFoundException;
import com.arosys.doqeap.exception.ValidationException;
import com.arosys.doqeap.exception.ValueNotFoundException;
import com.arosys.doqeap.mqmanager.MQConnectionManager;
import com.arosys.doqeap.serviceconfiguration.ServiceConfiguration;
import com.rabbitmq.client.Connection;
import java.io.IOException;
import java.net.URISyntaxException;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;


public class ThreadDemo 
{

    public static void main(String s[])
    {
        try {
            ServiceConfiguration sc=new ServiceConfiguration("e:\\07-10\\Development\\standardizationService\\StandardizeAccountService.xml");
            try {
                sc.loadProperties();
            } catch (IOException ex) {
                Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
            } catch (SQLException ex) {
                Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
            } catch (ValidationException ex) {
                Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
            } catch (DatabaseException ex) {
                Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
            } catch (URISyntaxException ex) {
                Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
            } catch (FileNotFoundException ex) {
                Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
            }
            MQConnectionManager mq=new MQConnectionManager(sc);
            Connection mQConnection = mq.getMQConnection();
            wokerThread wr=new wokerThread(sc,mQConnection);
            wr.init();
            Thread[] worker=new Thread[2];
            for(int i=0;i<worker.length;i++)
            {
                worker[i]=new Thread(wr,""+i);
                worker[i].start();
            }


        } catch (com.arosys.customexception.KeyNotFoundException ex) {
            Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NullObjectFoundException ex) {
            Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
        } catch (MQConnectionNotEstablished ex) {
            Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ValueNotFoundException ex) {
            Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
        } catch (KeyNotFoundException ex) {
            Logger.getLogger(ThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}

这里ThreadDemo类创建两个线程,而workerTheread类将从队列中侦听消息(RabbitMQ)。每个线程将从队列中读取消息并在指定的日志文件上写入日志消息。

worker0.log

2011-11-24 13:24:35 INFO wokerThread:73 - Thread name-0
2011-11-24 13:24:35 INFO wokerThread:74 - Appender Name logs\worker0.log

worker1.log

2011-11-24 13:24:35 INFO wokerThread:73 - Thread name-1
2011-11-24 13:24:35 INFO wokerThread:74 - Appender Name logs\worker1.log
2011-11-24 13:24:35 INFO wokerThread:88 - 0 :: Starting to listen to Request Queue. . . . . . . . . . . .Thread[0,5,main]
2011-11-24 13:24:35 INFO wokerThread:88 - 1 :: Starting to listen to Request Queue. . . . . . . . . . . .Thread[1,5,main]
2011-11-24 13:24:39 INFO wokerThread:93 - Thread[0,5,main] ::  Message picked up from Queue--com.rabbitmq.client.QueueingConsumer$Delivery@cfec48
2011-11-24 13:24:39 INFO wokerThread:93 - Thread[1,5,main] ::  Message picked up from Queue--com.rabbitmq.client.QueueingConsumer$Delivery@a17083
2011-11-24 13:24:39 INFO wokerThread:93 - Thread[0,5,main] ::  Message picked up from Queue--com.rabbitmq.client.QueueingConsumer$Delivery@e1d5ea
2011-11-24 13:24:39 INFO wokerThread:93 - Thread[0,5,main] ::  Message picked up from Queue--com.rabbitmq.client.QueueingConsumer$Delivery@a31e1b
2011-11-24 13:24:40 INFO wokerThread:93 - Thread[1,5,main] ::  Message picked up from Queue--com.rabbitmq.client.QueueingConsumer$Delivery@10da5eb

根据我的说法,thread0日志记录在worker0上同样适用于thread1。我无法确定问题所在。请帮助我吗?

此致

1 个答案:

答案 0 :(得分:3)

您正在使用相同的wokerThread实例初始化两个Thread。这样第一个worker的appender就会被第二个线程删除,并且会添加第二个日志文件(worker1)的appender。

尝试:

        // wokerThread wr=new wokerThread(sc,mQConnection); --> move this into the loop
        // wr.init(); --> move this into the loop
        Thread[] worker=new Thread[2];
        for(int i=0;i<worker.length;i++)
        {
            wokerThread wr=new wokerThread(sc,mQConnection); // --> moved into the loop
            wr.init(); // --> moved into the loop
            worker[i]=new Thread(wr,""+i);
            worker[i].start();
        }

等等,这还不够。您应该在每个wokerThread实例中配置不同的Logger实例。 Logger实例由其名称标识,因此在wokerThread.java方法的run()中,您可以使用不同的名称检索不同的Logger实例。在这里,您可以使用当前线程的名称来区分记录器:

  public void run()
  {
      ...
      String threadName = Thread.currentThread().getName(); // --> added line
      // --> now append thread's name to logger name:
      Logger logger1=LoggerFactory.getLogger(" com.demo.wokerThread_" + threadName,"resources/log4j.xml");
      logger1.removeAllAppenders();
      ...
   }