Java 抽象类中的同步方法是如何工作的?

Java 抽象类中的同步方法是如何工作的?,java,multithreading,synchronization,Java,Multithreading,Synchronization,我想在线程之间同步对象,这些对象扩展了一个抽象类: public abstract class GraphicObject { public synchronized void test(){ //work... } } class Circle extends GraphicObject { } class Rectangle extends GraphicObject { } 考虑这个测试类: public class Class { vo

我想在线程之间同步对象,这些对象扩展了一个抽象类:

public abstract class GraphicObject {

    public synchronized void test(){
        //work...
    }
}

class Circle extends GraphicObject {

}
class Rectangle extends GraphicObject {

}
考虑这个测试类:

public class Class {
     void main(){
        GraphicObject a=new Circle();
        GraphicObject b=new Rectangle();
        Runnable r1 = new MyThread(a);
        new Thread(r1).start();
        Runnable r2 = new MyThread(b);
        new Thread(r2).start();
    }

     private class MyThread implements Runnable {

       private GraphicObject g;
       public MyThread(GraphicObject g) {
          this.g=g;
       }
       public void run() {
          g.test();
       }
    }
}
在这种情况下,
a
b
是具有相同抽象类的独立对象。
test()
方法是否同步在一起?如果一个线程调用
a.test()
b.test()
锁定到所有其他线程


我希望不会,因为它们是不同的对象。

首先,您的代码无法编译;不能将抽象方法与主体一起使用,也不能将抽象方法标记为已同步,尽管后者是一个

通常,方法上的
synchronized
关键字的工作原理如下:

methodDeclaration() {
    synchronized (this) {
      ....
    }
}
这意味着它在一个对象的实例上是同步的,这反过来意味着你的例子中的这两个方法在不同的锁上是同步的,分别在
a
b
上。

你的
test()
方法在实例上是同步的。因此,由于
a
b
是不同的实例(即使来自不同的类),它们不会相互锁定

如果你想要这种行为,你必须使用

synchronized (GraphicObject.class) {
    ...
}

这只能在方法实现中完成,因此没有机会从抽象父类强制执行它。

任何同步都绑定到调用该方法的实例。不管它是否是一种抽象的方法;在您的示例中,在示例中生成锁的唯一方法是从两个不同的线程调用
a.test()
,因为同步是在
a
,而不是
test()
。如果是通过类同步的静态方法,则情况会有所不同。

抽象方法无法同步。这是在:

如果包含关键字abstract的方法声明还包含任何一个关键字private、static、final、native、strictfp或synchronized,则这是编译时错误


重写抽象声明的具体方法可以同步;在这种情况下,它的工作原理与任何其他同步方法一样:它锁定
实例。

这不是真的,好吧,我没有注意到他方法中的
摘要
。但是它不会编译。我编辑代码删除了双抽象键,这是一种类型。现在应该可以编译了。你试过编译吗?是的,但我简化了代码,所以删除了一些东西。现在我将测试类编辑为可编译的,但是我的问题实际上是理论上的。我不确定链接的问题是否相同。我同意:所谓的“重复”回答了不同的问题。我认为问题在于你的头衔。它似乎在问你为什么不能声明一个抽象的
synchronized
方法,但你的问题的主体实际上是关于抽象类中的一个具体的
synchronized
方法(即,一个碰巧还声明了至少一个其他抽象方法的类)。@jameslarge你是对的,我是说抽象类中的同步方法。。。我正在编辑itI,我没有发现编译错误,我的IDE(eclipse)使用您的编辑进行编译,
test()
不再是抽象方法。您询问了abstract synchronized方法,但随后编辑了您的问题,使其不包含任何内容。好的,但现在test()已同步?是的--它的工作原理与超级类不是抽象的一样。该方法是同步的,这意味着它在调用该方法的每个实例的
this
上进行同步。