/**
  * 该程序是生成日志文件,再将信息输入到日志文件
  * 该程序是单例,由多线程访问
  */
public class FileLogger
{
     
     private String date = "";     private Printwriter Writer = null     public void log(String msg) 
     {        // Construct the timestamp we will use, if requested
        Timestamp ts = new Timestamp(System.currentTimeMillis());
        String tsString = ts.toString().substring(0, 19);
        String tsDate = tsString.substring(0, 10);        // If the date has changed, switch log files
        if (!date.equals(tsDate)) 
        {
            synchronized (this) //该锁是锁定哪个对象(我知道是该对象的实例),具体是锁                                
                                // 里面的哪一个,为什么
            {
                if (!date.equals(tsDate)) 
                {
                    close();
                    date = tsDate;
                    open();
                 }
             }
          }          // Log this message, timestamped if necessary
        if (writer != null) 
        {
            
            writer.println(tsString + " " + msg);
           
         }
      }      private void open()
      {        // Create the directory if necessary
        File dir = new File(directory);
        if (!dir.isAbsolute())
            dir = new File(System.getProperty("user.dir"), "webroot");
        dir.mkdirs();        // Open the current log file
        try 
        {
            String pathname = dir.getAbsolutePath() + File.separator +
                "log_" + date + ".txt";
            writer = new PrintWriter(new FileWriter(pathname, true), true);
        } 
        catch (IOException e) 
        {
            writer = null;
        }      }
}

解决方案 »

  1.   

    这里只是要串行化执行log的那部分,在synchronized(this)的地方可以synchronized其它任何东西都可以,不一定就是this,除了null,都能达到功能
      

  2.   

    如果两个线程同时往FileWriter里写数据,a写了一半的时候,突然b开始写,a也继续写,这写出来的东西不乱套了吗?
      

  3.   

    那应该锁下面的writer.println(tsString + " " + msg)才是,到他那里都释放了锁
      

  4.   

    纠正一下,println是线程安全的操作    public void println(String x) {
    synchronized (lock) {
        print(x);
        println();
    }
        }