【问题标题】:How to prevent method from being executed concurrently by different threads within the same class instance如何防止同一类实例中的不同线程同时执行方法
【发布时间】:2018-12-03 10:33:35
【问题描述】:

假设我有两个线程,都从给定的类实例 A 开始。线程必须从同一个实例执行一个方法,但一次一个。我尝试使该方法同步,但显然它适用于尝试调用该方法的不同实例(据我了解;如果我错了,请原谅我)。

那么,我应该如何实现这一点,最好采用标准或推荐的方式?

编辑:这是相关代码:

public class A {
.
.
.
  public void method1(){

    ExecutorService threadObject = Executors.newSingleThreadExecutor();
            threadObject.execute(new Runnable(){
                @Override
                public void run() {
                    try {
                        while (someCondition) {
                          //Here's one invocation
                          someObject = readObject();
                        }
                    }
                    catch (IOException | ClassNotFoundException ex) {}
                }
            });

    //Here's the other invocation
    while(someCondition){
      someObject = readObject();
    }
  }

  //Here's the synchronized method
  private synchronized SomeClass readObject() throws IOException, ClassNotFoundException{
          return (SomeClass) incomingResponses.readObject();
  }

  //Main method to instantiate the class
  public static void main(String ... args) {
    A = new A();
    A.method1();
  }
}

我仍然不确定我做错了什么。

【问题讨论】:

  • 请发布您的同步代码。
  • @AlexeySoshin 我已经添加了相关代码。
  • 我在你的代码中看不到 2 个线程在 A 的同一个实例上工作。我只看到 1 个线程,没有 A 的实例。
  • @AlexeiKaigorodov,同意,示例不完整,但有两个线程:主线程和threadObject 执行程序创建的线程。跨度>
  • @AlexeiKaigorodov 抱歉,应该更彻底地审查 sn-ps;希望代码现在更有意义

标签: java multithreading concurrency


【解决方案1】:

synchronized 方法是一种捷径。 IMO,在开始使用快捷方式之前,您应该学会这样做:

如果你有这个:

class A {
    synchronized SomeType myMethod(...) {
        doSomeStuff(...);
        ...
        return someThing;
    }
}

这是用顶级synchronized statement编写方法声明的快捷方式:

class A {
    SomeType myMethod(...) {
        synchronized (this) {
            doSomeStuff(...);
            ...
            return someThing;
        }
    }
}

IMO,您应该先学习如何使用同步语句,然后在您对同步语句的工作原理有了更好的了解后才使用同步方法。

【讨论】:

  • 肯定会对此进行更多研究。与同步方法相比,使用同步语句有什么优势?
  • 使用同步语句没有任何优势,但你原来的问题表明你并不完全理解Java的内在同步。我的意思是你应该首先理解 synchronized 语句,因为这样,synchronized 实例方法和synchronized 类方法就很容易解释了。
【解决方案2】:

你的说法是错误的。引用documentation的相关例子:

  • 首先,对同一对象的同步方法的两次调用不可能交错。当一个线程正在执行时 对象的同步方法,调用的所有其他线程 同一对象块的同步方法(暂停执行) 直到第一个线程处理完对象。
  • 其次,当一个同步方法退出时,它会自动与任何后续的方法建立一个happens-before关系 为同一对象调用同步方法。这个 保证对象状态的更改对所有人可见 线程。

因此,应用于方法的synchrinzed 关键字将不允许在特定对象实例上同时调用该方法。

【讨论】:

  • 我已添加相关代码以进行更多说明
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-24
  • 2020-04-06
相关资源
最近更新 更多