现项目有一个需求,许多并发的线程需要不停的写数据到数据库中,同时为了数据安全??nnd,要实时将数据写到服务器本地文件中。一天生成一个日志文件。本来我的意思是可以起一个线程定时处理,别人认为这个还不是实时的,万一碰到数据写入数据库失败,还能在备份文件中找到结果。- -请问写文件时仅仅实现synchonized 就可以满足需求了吧。但我考虑几百个并发同时在服务器上不停的进行io操作,要把服务器搞崩溃的。有没有更好的解决办法呢。

解决方案 »

  1.   

    我觉得你可以用log4j
    先建立一个log对象,可以把这个对象设置为静态的,
    以便各个线程都可以直接调用,就像使用一个工具
    然后在各个线程需要写文件的地方使用这个log对象写就可以了阿
    也不需要你自己去处理io
      

  2.   

    package nrsoft.db;import java.io.*;
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Date;public final class Debug
    {    private static Debug instance = null;
        private static SimpleDateFormat dateFormat = null;
        private static FileOutputStream fos = null;    private Debug()
        {
        }    static synchronized Debug init(String path)
        {
            String file = "";
            String fullPath = "";
            if(instance == null)
            {
                instance = new Debug();
                dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                file = "" + (new SimpleDateFormat("yyyy-MM-dd")).format(new Date()) + ".log";
                try
                {
                    fullPath = path + "\\" + file;
                    fos = new FileOutputStream(fullPath, true);
                }
                catch(IOException ioe)
                {
                    System.err.println("Cannot open file " + file + "," + fullPath);
                }
            }
            return instance;
        }    public static synchronized void log(String msg)
        {
            String s2 = dateFormat.format(new Date()) + " " + msg + "\n";
            if(instance != null)
                instance.writeFile(s2);
            else
                System.err.println(s2);
        }    private String writeFile(String msg)
        {
            if(fos == null)
                return "Log file cannot be opened";
            try
            {
                fos.write(msg.getBytes());
                fos.flush();
            }
            catch(IOException ex)
            {
                return ex.getMessage();
            }
            return null;
        }    public static String getExceptionMsg(Exception e)
        {
            String msg = e.getMessage();
            return msg;
        }}
    ///调用
    Debug.log(Debug.getExceptionMsg(ex));
      

  3.   

    启动数据库的常规日志,他会记录你所有的SQL操作。
      

  4.   

    能不能具体点,来点代码,对log4j不熟悉。
    怎么弄全局log对象,
      

  5.   

    1.用来写日志的工具类import org.apache.log4j.PropertyConfigurator;
    import org.apache.log4j.Category;
    import org.apache.log4j.Logger;
    import org.apache.log4j.Priority;public class Test1 { public static Logger logger_debug;  //静态的log对象

    private void setLog() { logger_debug = Logger.getLogger("ToDebugFile");    //设置log对象的属性

    PropertyConfigurator.configure("Test1_log4j.properties");  //设置log4j的属性文件

    }}
    2.各线程中log对象的使用public class Test2 extends Thread { public void run()  {

    //some other codes

    Test1.logger_debug.debug("debug");    //记录debug级别的日志
    Test1.logger_debug.info("##### Test2 Info#####");   //记录info级别的日志
            Test1.logger_debug.warn("##### Test2 Warning#####"); //记录warning级别的日志
    Test1.logger_debug.error("##### Test2 Error#####");  //记录error级别的日志
    }}

    3.log4j的属性文件--Test1_log4j.properties 的内容log4j.category.ToDebugFile = debug,debugfile
    log4j.appender.debugfile=org.apache.log4j.DailyRollingFileAppender  //1天切换一次日志
    log4j.appender.debugfile.File=debug_                                //log文件名
    log4j.appender.debugfile.DatePattern=yyyy-MM-dd_HH-mm'.log'         //可以在文件名上加上log的出力时间
    log4j.appender.debugfile.layout=org.apache.log4j.PatternLayout 
    log4j.appender.debugfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %p%m%n  //log出力的样式具体的log4j属性文件的解释,网上有很多,一查就明白了,我这里只是简单的说一下
      

  6.   

    真的要实时要使用操作系统提供的越过磁盘缓存的API来实现,各个平台是不一样的。log4j可以满足一般的需求。
      

  7.   

    之前描述的有问题,是很多类的实例都需要向一个文件中记录日志。public class TestLog {
    private static final Logger logger = Logger.getLogger(TestLog.class); public static void log(String logs){
    logger.info(logs);
    }}我其他类中记录日志时都调用MyLog.log("xxx");这样不会出现写文件时锁的问题了吧
      

  8.   

    不会有问题啊
    这个是log4j的功能阿你多少个类去调用都没有问题的顺便说一下你上面的代码哦
    你这样写在打印日志的时候不够灵活假如,在A类中,我想打一个debug级别的log,还想打一个error级别的
    用你这个方法就不行了
    还有,比如在各个类中,组成日志内容的时候,一般中间会带有其他变量等
    而且各条日至的变量个数可能都不固定吧
    如果调你这个方法的话,怎莫处理呢所以,偶觉得还是把log对象写成static的,在哪里出log就在哪里用这个log对象
    而且日志级别和内容都可以灵活变化