首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java同步方法锁在对象上,还是方法上?

Java同步方法锁在对象上,还是方法上?
EN

Stack Overflow用户
提问于 2010-06-16 01:38:08
回答 5查看 197.8K关注 0票数 212

如果我在同一个类中有两个同步的方法,但每个方法都访问不同的变量,那么两个线程可以同时访问这两个方法吗?锁定是否发生在对象上,或者它是否像同步方法中的变量一样具体?

示例:

class X {

    private int a;
    private int b;

    public synchronized void addA(){
        a++;
    }

    public synchronized void addB(){
        b++;
    }

}

两个线程可以同时访问执行x.addA()和x.addB()的类X的相同实例吗?

EN

回答 5

Stack Overflow用户

发布于 2010-06-16 01:45:21

在方法声明上同步的是以下内容的语法糖:

 public void addA() {
     synchronized (this) {
          a++;
     }
  }

在静态方法上,这是语法上的糖:

 ClassA {
     public static void addA() {
          synchronized(ClassA.class) {
              a++;
          }
 }

我认为,如果Java设计人员当时知道什么是现在所理解的同步,他们就不会添加语法糖,因为这往往会导致糟糕的并发实现。

票数 73
EN

Stack Overflow用户

发布于 2010-06-16 02:05:10

您可以执行类似以下的操作。在本例中,您使用的是a和b上的锁来同步,而不是" this“上的锁。我们不能使用int,因为原始值没有锁,所以我们使用Integer。

class x{
   private Integer a;
   private Integer b;
   public void addA(){
      synchronized(a) {
         a++;
      }
   }
   public synchronized void addB(){
      synchronized(b) {
         b++;
      }
   }
}
票数 4
EN

Stack Overflow用户

发布于 2015-08-07 18:57:36

如果您有一些方法是不同步的,并且正在访问和更改实例变量。在您的示例中:

 private int a;
 private int b;

当其他线程处于同一对象的同步方法中时,任意数量的线程可以同时访问这些非同步方法,并且可以对实例变量进行更改。例如:-

 public void changeState() {
      a++;
      b++;
    }

您需要避免非同步方法正在访问实例变量并更改它的场景,否则使用同步方法就没有意义了。

在下面的场景中:

class X {

        private int a;
        private int b;

        public synchronized void addA(){
            a++;
        }

        public synchronized void addB(){
            b++;
        }
     public void changeState() {
          a++;
          b++;
        }
    }

只能有一个线程处于addA或addB方法中,但同时可以有任意数量的线程进入changeState方法。没有两个线程可以同时进入addA和addB (因为对象级锁定),但同时可以有任意数量的线程进入changeState。

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

https://stackoverflow.com/questions/3047564

复制
相关文章

相似问题

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