首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >java中形参的同步

java中形参的同步
EN

Stack Overflow用户
提问于 2011-03-10 03:21:37
回答 6查看 2.6K关注 0票数 5

假设我有一个被两个或更多线程访问的方法,我想让它成为线程安全的。

代码语言:javascript
复制
public int getVal(int x, int y, MyClass myObj)  
{
   int z;

   z = getInt(myObj);

   return x + y + z;  
}

在这种情况下,我认为我们不需要对x+y进行同步,因为它们是原语。

让我们假设getInt(myObj)修改了myObj的状态,这会影响z的值。

因此,我将不得不为行z = getInt(myObj);提供同步,但仅当两个线程在'myObj‘引用中传递相同的实例时。作为应用编程接口的编码器,我不知道这两个线程是否会为“myObj”传递相同的实例。在某些情况下,这些线程可能会在“myObj”引用中传递相同的MyClass实例,而在其他情况下,它们可能会在“myObj”引用中传递不同的MyClass实例。

那么,如何确保z = getInt(myObj)行的线程安全呢?(当然,我们不希望在传递的实例不同时进行同步,而只需要在传递的实例相同时进行同步。I很明显,这是无法确定的)。

假设MyClass不能成为不可变的,我认为以下可能是一个解决方案。

代码语言:javascript
复制
synchronized(myObj)
{
  z = getInt(myObj);
}

这是一个正确的解决方案吗?还有,我们还可以用什么其他方式来确保线程的安全性

代码语言:javascript
复制
z = getInt(myObj); (but only in case of different instances)?
EN

回答 6

Stack Overflow用户

发布于 2011-03-10 03:31:42

你所拥有的是正确的。当你锁定一个对象时,它锁定的是那个实例,而不是那个类。( synchronize on a object )因此,如果我将一个对象的相同*实例*传递给两个不同的方法,它将正确地锁定该对象。但是,如果我传递两个不同实例,就不会有任何锁定,因为这两个实例都有自己的锁。

票数 3
EN

Stack Overflow用户

发布于 2011-03-10 03:32:56

如果getInt不修改this的状态,那么该方法是线程安全的。myObj对象的线程安全性取决于它的类: MyClass或持有它的对象的可响应性。并不是所有的方法都有责任,这些方法可能会把它作为一个参数。

您的解决方案(synchronized(myObj))是正确的:如果两个线程使用相同的myObj,两个线程将无法并发执行getInt方法。如果两个myObjs不同,它们将并发执行。

票数 2
EN

Stack Overflow用户

发布于 2011-03-10 04:45:56

代码语言:javascript
复制
synchronized(myObj) {   z = getInt(myObj); } 

将会做你想做的事情,但是在参数上同步会产生许多其他问题。例如,某个其他线程可能已经在该对象上同步(例如,可能该对象有一个正在被调用的同步方法),您可能会遇到死锁情况。

应该像封装其他任何东西一样封装同步。最好的解决方案是将getInt方法添加到MyClass中,并在该方法中的某个私有成员上进行同步。这样别人就不会弄乱你用来实现同步化的东西了。

例如:

代码语言:javascript
复制
public class MyClass {
  private Object lockObject = new Object();
  public int getInt() {
    synchronized(lockObject) {
      // do your thing
    }
  }
}

请看这里:Avoid synchronized(this) in Java?引用了封装同步的重要性。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5251024

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档