我们将举一些例子来看看静态方法是否是线程安全的。
示例 1:
public static String concat (String st1, String str2) {
return str1 + str2
}
现在上面的方法是线程安全的。
现在我们将看到另一个不是线程安全的示例。
示例 2:
public static void concat(StringBuilder result, StringBuilder sb, StringBuilder sb1) {
result.append(sb);
result.append(sb1);
}
如果您看到这两种方法都非常原始,但仍然一种是线程安全的,另一种则不是。为什么?两者有什么区别?
实用程序中的静态方法是否易于非线程安全?很多问题对吧?
现在每件事都取决于您如何实现方法以及您在方法中使用的对象类型。您是否使用线程安全对象?这些对象/类是可变的吗?
如果您在示例 1 中看到 concat 方法的参数是 String 类型,它是不可变的并且按值传递,因此该方法是完全线程安全的。
现在在示例 2 中,参数是可变的 StringBuilder 类型,因此其他线程可以更改 StringBuilder 的值,这使得该方法可能是非线程安全的。
这又不是完全正确的。如果您使用局部变量调用此实用程序方法,那么您永远不会遇到与线程安全相关的任何问题。因为每个线程都使用自己的局部变量副本,所以您永远不会遇到任何线程安全问题。但这超出了上述静态方法的范围。这取决于调用函数/程序。
现在实用程序类中的静态方法是一种正常的做法。那么我们该如何避免呢?如果您看到示例 2,我正在修改第一个参数。现在,如果你想让这个方法真正线程安全,那么你可以做一件简单的事情。要么使用非可变变量/对象,要么不更改/修改任何方法参数。
在示例 2 中,我们已经使用了可变的 StringBuilder,因此您可以更改实现以使静态方法线程安全,如下所示:
public static String concat1(StringBuilder sb, StringBuilder sb1) {
StringBuilder result = new StringBuilder();
result.append(sb);
result.append(sb1);
return result.toString();
}
再次回到基础知识,请始终记住,如果您使用的是不可变对象和局部变量,那么您离线程安全问题还有很长的路要走。
来自北极(https://nikhilsidhaye.wordpress.com/2016/07/29/is-static-method-in-util-class-threadsafe/)感谢Nikhil Sidhaye这篇简单的文章