如何保证实用静态方法的线程安全?(How to ensure thread safety of ut

2019-07-05 12:36发布

有没有通用的方法或规则退出,使我们可以确保在任何应用中的各种实用工具类专门用于静态方法的线程安全。 在这里,我想特别指出的Web应用程序的线程安全。

这是众所周知的与不可变对象静态方法的参数是线程安全的,可变对象都没有。

如果我有一些操作实用方法java.util.Date和方法接受的一个实例java.util.Date ,那么这种方法就不会是线程安全的。 那么如何使线程安全的,而不改变参数传递的方式吗?

public class DateUtils {

    public static Date getNormalizeDate(Date date) {
        // some operations
    }   
}

也就是类javax.faces.context.FacesContext可变的? 难道是线程安全的这个类的一个实例传递给这样的静态实用方法?

类此列表,其中的实例可以或不能作为参数传递,可能很长; 所以,我们应该记住什么分,写这样的实用工具类的代码?

Answer 1:

众所周知,随着不可变对象作为参数的静态方法是线程安全的,可变对象都没有。

我会质疑这一点。 传递给方法的参数被存储在堆栈中,这是一个每线程成语上。

如果你的参数是一个可变的对象,如Date ,那么你需要确保其他线程在同一时间在其他地方没有修改它。 但是,这无关你的方法的线程安全另当别论。

您发布的方法是线程安全的。 它维护没有国家,只有在它的参数进行操作。

我强烈建议你阅读Java并发实践 ,或类似的书献给线程安全在Java中。 这是一个复杂的问题,不能通过几个StackOverflow的答案妥善处理。



Answer 2:

由于类并无持有任何成员变量,你的方法是无状态的(它仅使用局部变量和参数),因此是线程安全的。

调用它可能不是线程安全的,但是那是另外一个讨论的代码。 例如,日期不是线程安全的,如果调用代码读取已被写入由另一个线程一个日期,则必须在时间写作和阅读的代码中使用适当的同步。



Answer 3:

由于JVM的结构,局部变量,方法参数和返回值本质上是“线程安全的。” 但是,如果你适当地设计你的类的实例变量和类变量只会是线程安全的。 更在这里



Answer 4:

我想只要方法启动建议创建(可变)对象的副本,并使用副本,而不是原来的参数。

像这样的事情

public static Date getNormalizeDate(Date date) {
    Date input = new Date(date.getTime());
    // ...
}


Answer 5:

以下是我想起来了:想像一个营地(这是一个静态方法)。 作为一个露营,我能有一大堆在我的背包对象带来的(这是在栈上传递的参数)。 露营地为我提供了把我的帐篷和我的野营炉,等的地方,但如果不露营的唯一事情是让我修改我自己的对象则是线程安全的。 营地甚至可以创建东西凭空(的FirePit firepit = new FirePit(); ),这也得到在堆栈上创建的。

在任何时候,我可以用我在我的ruckstack所有对象和其他任何露营者可以出现一个消失,做他们正在做的正是他们最后一次消失了。 不同的线程在这个营地将无法访问对象在其他线程的堆栈中创建营地。

假设只有一个野营炉(野营炉的一个对象,而不是单独的实例)中。 如果想象的一些舒展我共用一个野营炉对象,然后还有多线程方面的考虑。 我不想把我的野营炉,消失,然后重新出现后,其他一些露营者已经把它关闭 - 我会永远被检查,如果我的热狗做,它永远不会是。 你将不得不把一些同步的地方......在野营炉类,在被调用营地的方法,或在营地本身......但像邓肯·琼斯说,“这是一个不同的问题。”

需要注意的是,即使我们在 -static营地对象的独立实例野营,共享野营炉也有同样多线程方面的考虑。



Answer 6:

我看到了很多答案,但没有真正指出的原因。

因此,这可以被认为是这样的,只要创建一个线程,它与它自己的堆栈中创建(我猜的堆栈在创建时的大小为〜2MB)。 所以,实际上发生的任何执行情况本线程堆栈的范围内。 任何变量,创建在堆中生活,但它是生活引用在栈中的例外是不生活在线程堆栈静态变量。

任何函数调用你做实际上是推到线程堆栈,无论是静态的还是非静态的。 由于完整的方法压入堆栈,任何变量创造,发生生活堆栈(再次例外是静态变量),只有一个线程可以访问内。

所以,直到他们改变一些静态变量的状态,所有的方法都是线程安全的。



文章来源: How to ensure thread safety of utility static method?