在Java中,不使用静态或类变量的方法需要同步吗?

发布于 2024-10-13 04:51:08 字数 93 浏览 2 评论 0原文

仅在内部使用局部变量的方法是否会遇到任何线程问题?有人提到,带有局部变量的方法被复制到每个线程堆栈帧中以供使用,并且不需要同步多线程实现,除非它使用类级别或静态引用/变量?

Do methods that only use local variables inside suffer any threading issues ?. Somewhere it was mentioned that the method with local variables are copied to each thread stack frame to work with and do not need to synchronized for multithreaded implementation unless it uses class level or static references/variables ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

温柔戏命师 2024-10-20 04:51:08

如果您的方法仅对参数和本地定义的(而不是类成员)变量进行操作,那么需要担心的同步问题为零。

但是...

这意味着您使用的任何可变引用类型必须仅在您的方法范围内生存和消亡。 (不可变引用类型在这里不是问题。)例如,这不是问题:

int doSomething(int myParameter)
{
  MyObject working_set = new MyObject();
  interim = working_set.doSomethingElse(myParameter);
  return working_set.doSomethingElseAgain(interim);
}

在您的方法中创建一个 MyObject 实例,在您的方法中完成所有工作,并且正在咳血,等待当您退出方法时被 GC 剔除。

另一方面,这可能是一个问题:

int doSomething(int myParameter)
{
  MyObject working_set = new MyObject();
  interim = working_set.doSomethingElse(myParameter);
  another_interim = doSomethingSneaky(working_set);
  return working_set.doSomethingElseAgain(another_interim);
}

除非您确切知道 doSomethingSneaky() 中发生了什么,否则您可能需要在某处进行同步。具体来说,您可能必须对 working_set 上的操作进行同步,因为 doSomethingSneaky() 可能会存储对本地 working_set 对象的引用并传递该对象当您仍在自己的方法或 working_set 的方法中执行操作时,转到另一个线程。在这里你必须更加防御。

当然,如果您只使用原始类型,甚至调用其他方法并传递这些值,也不会成为问题。

If your method only operates on parameters and locally-defined (as opposed to class member) variables then there are zero synchronization problems to worry about.

But...

This means any mutable reference types you use must live and die only within the scope of your method. (Immutable reference types aren't a problem here.) For example this is no problem:

int doSomething(int myParameter)
{
  MyObject working_set = new MyObject();
  interim = working_set.doSomethingElse(myParameter);
  return working_set.doSomethingElseAgain(interim);
}

A MyObject instance is created within your method, does all of its work in your method and is coughing up blood, waiting to be culled by the GC when you exit your method.

This, on the other hand, can be a problem:

int doSomething(int myParameter)
{
  MyObject working_set = new MyObject();
  interim = working_set.doSomethingElse(myParameter);
  another_interim = doSomethingSneaky(working_set);
  return working_set.doSomethingElseAgain(another_interim);
}

Unless you know for sure what's going on in doSomethingSneaky(), you may have a need for synchronization somewhere. Specifically you may have to do synchronization on the operations on working_set because doSomethingSneaky() could possibly store the reference to your local working_set object and pass that off to another thread while you're still doing stuff in your method or in the working_set's methods. Here you'll have to be more defensive.

If, of course, you're only working with primitive types, even calling out to other methods, passing those values along, won't be a problem.

别再吹冷风 2024-10-20 04:51:08

仅在内部使用局部变量的方法不会遇到任何线程问题吗?

在非常简单的意义上是正确的,但让我们明确一下 - 我认为只有在以下情况下才是正确的:

  • 这样的方法仅使用局部变量,这些变量是基元或对可变实例的引用,否则无法通过任何其他方式在方法外部访问这些变量.

  • 此类方法仅调用线程安全的方法。

在某些方面,这些规则可能会被违反:

  • 局部变量可能会被初始化为指向也可以在方法外部访问的对象。例如,局部变量可以指向单例 (Foo bar = Foo.getSingleton())。

  • 如果将实例作为参数传递给保留对实例引用的外部方法,则由局部变量保存的本地实例可能会“泄漏”。

  • 没有实例变量并且只有一个没有局部变量的方法的类仍然可以调用另一个非线程安全的类的静态方法。

Does methods that only use local variables inside, do not suffer any threading issues ?

True in a very simplistic sense, but lets be clear - I think this is only true if:

  • such a method uses only local variables that are primitives or references to mutable instances that cannot otherwise be accessed outside the method by any other means.

  • such a method invokes only methods that are thread-safe.

Some ways these rules could be violated:

  • A local variable could be initialized to point to an object that is also accessible outside the method. For example, a local variable could point to a singleton (Foo bar = Foo.getSingleton()).

  • A local instance held by a local variable could "leak" if the instance is passed as a argument to an external method that keeps a reference to the instance.

  • A class with no instance variables and with only a single method with no local variables could still call the static method of another class that is not thread-safe.

酒解孤独 2024-10-20 04:51:08

这个问题很笼统,所以请不要期望我的回答有任何具体之处。

1_ 与实例方法相比,我们需要更加小心地使用静态方法。

2_ @Justmy Correctopinion 是正确的,但他描述的一些术语需要更详细地阐述才能完美。 (即使静态方法仅适用于局部变量,仍然存在竞争条件的可能性。)

3_ 对我来说,有一些简单的规则可以帮助我分析线程安全性。

了解封装在其中的每个组件是否可共享。因此,最简单的解决方案是减少所有变量的范围,仅在绝对必要时增加范围,并且如果组件对对象执行突变,则通常不是线程安全的。

4_ 使用工具支持对线程安全进行静态代码分析。 (想法有检查线程插件)。

5_ 切勿使用静态方法来执行对象突变。如果调用静态变量导致对象突变,那么开发人员只是在规避 OOPS。

6_ 始终记录线程安全。请记住,有些方法在开发时可能不需要同步,但可以很容易地使其成为非线程安全的。

7_ 最后但可能是我最重要的一点是,确保大多数对象都是不可变的。根据我的经验,大多数时候,我从来不需要让我的许多对象变得可变。 (在极少数情况下,当需要更改对象状态时,防御性复制/新对象创建几乎总是更好。)

The question is very generic, so please do not expect any specificity from my answer.

1_ We need to more careful with static methods than say instance methods.

2_ @Justmycorrectopinion is about right, but some of the terms he described needs to be more elaborated to be perfect. ( Even if the static method, only works on local variable, there is still possibility of race condition.)

3_ For me there are simple rules that have helped me analyze thread safety.

Understand if each components encapsulated within it is shareable or not. So the simplest solution is to reduce the scope of all variable and only increase scope if absolutely necessary and if component perform mutation on a object, its usually not thread safe.

4_ Use tooling support to perform static code analysis on thread safety. (Idea has checkthread plugin).

5_ Never use static method to perform object mutation. If calling static variable causes object mutation, then the developer is just circumventing OOPS.

6_ Always document thread safety. Remember some method may not need to be synchronized when you develop, but can be made not thread safe very easily.

7_ Last but probably my most important point, make sure most of your objects are immutable. In my experience, most of the time, I never had to make many of my objects mutable. (In rare cases when object state needs to be changed, defensive copying / New Object Creation is almost always better. )

っ左 2024-10-20 04:51:08

您无需担心局部变量。然而实例变量是需要关心的。

You do not need to worry about local variables. Instance variables however are something to care about.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文