当前位置: 首页 > 知识库问答 >
问题:

如何使静态类线程安全?

姜泳
2023-03-14

我有一个简单的静态日志记录类。但是,它肯定不是线程安全的,因为每个调用都试图写入同一个文件。我得到了这些例外情况:

The process cannot access the file 'logfile.txt' because it is being used by another process.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 
...

什么是最好的方法使它的线程安全?

public static class Logger
{
    private static readonly string LOG_FILENAME = "logfile.txt";
    private static readonly string LOG_FOLDER = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "App name");
    private static readonly string LOG_FULLPATH = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "App name", LOG_FILENAME);

    public static void LogMessageToFile(string msg)
    {
        msg = string.Format("{0:G}: {1}{2}", DateTime.Now, msg, Environment.NewLine);
        File.AppendAllText(LOG_FULLPATH, msg);
    }
}

作为一个日志记录函数,我希望能够从代码的许多不同部分访问它(因此,我选择它为静态的原因)。然而,我想要使它成为线程安全的,我总是必须向它传递一个公共对象来lock(),我认为这违背了静态函数的目的。还是事实并非如此?

共有1个答案

武骁
2023-03-14
public static class Logger
{
    private static readonly string LOG_FILENAME = "logfile.txt";
    private static readonly string LOG_FOLDER = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "App name");
    private static readonly string LOG_FULLPATH = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "App name", LOG_FILENAME);

    private static Object theLock=new Object();

    public static void LogMessageToFile(string msg)
    {
        msg = string.Format("{0:G}: {1}{2}", DateTime.Now, msg, Environment.NewLine);
        lock (theLock)
        {
            File.AppendAllText(LOG_FULLPATH, msg);
        }
    }
}
 类似资料:
  • 问题内容: 我想将Calendar用于某些静态方法并使用一个静态字段: 现在,我读到java.util.Calendar不是线程安全的。如何使该线程安全(应该是 静态的 )? 问题答案: 如果不是,则不能创建线程安全的东西。在的情况下,即使从中 读取 数据也不是线程安全的,因为它可以更新内部数据结构。 如果有可能,我建议改用Joda Time: 大多数类型是不可变的 不可变类型是线程安全的 无论如

  • 本文向大家介绍静态内部类单例 线程安全-Java版相关面试题,主要包含被问及静态内部类单例 线程安全-Java版时的应答技巧和注意事项,需要的朋友参考一下 我比较倾向于使用静态内部类的方法,这种方法也是《Effective Java》上所推荐的。 这种写法仍然使用JVM本身机制保证了线程安全问题;由于 SingletonHolder 是私有的,除了 getInstance() 之外没有办法访问它,

  • 问题内容: 假设我有一些Java代码: 如果一个线程正在初始化SomeClass的对象,并且在第二个线程想要再次加载SomeClass的过程中正在初始化静态块中的值,那么该静态块会怎样?即使第一个线程未完成,第二个线程是否仍假设它已初始化而忽略了它?还是发生其他事情? 问题答案: 如果第一个线程尚未完成对SomeClass的初始化,则第二个线程将阻塞。 Java语言规范的12.4.2节中对此进行了

  • 问题内容: 如标题所述,为什么静态嵌套类单例线程安全? 问题答案: 您显示的代码在技术上不是线程安全的。这种狡猾的代码通常会造成混乱。 该代码应如下所示: 在这里,我们在()的静态初始化程序中进行分配,任何以正确 的事前发生 关系访问它的线程都可以看到它。嵌套类没有什么特别的,它只允许使用外部类而无需立即构造单例对象。几乎可以肯定,这是完全 没有意义的,但似乎可以使某些人满意。 和以往一样,[ 可

  • 问题内容: 是否可以通过任何常规方法或规则来确保专门用于任何应用程序的各种Utility类的静态方法的线程安全性。在这里,我想特别指出Web应用程序的线程安全性。 众所周知,以不可变对象作为参数的静态方法是线程安全的,而可变对象不是。 如果我有一个实用程序方法可用于的某些操作,并且该方法接受的实例,则该方法将不是线程安全的。那么如何在不更改参数传递方式的情况下使其成为线程安全的呢? 课堂也是可变的

  • 问题内容: 我试图基于初始化按需持有人习惯用法创建一个线程安全的单例类。这是我的代码 我的期望是以线程安全的方式初始化ExecutorService,并且那里只有一个实例(静态)。 这段代码是实现了这一目标-还是需要任何更改? 问题答案: 根据SEI 指南,您的方法很好。 但是,由于我们有枚举,因此可以使用枚举的简单方法: 而且,如果您想变得真正聪明,还可以定义枚举实现的接口。因为这样您以后可以