【问题标题】:In Java what happens if two classes call a method in a third class at the same moment?在 Java 中,如果两个类同时调用第三个类中的方法会发生什么?
【发布时间】:2011-01-30 13:41:11
【问题描述】:

在我的项目中,我有一个由客户端类调用的游戏类。此时游戏类写入文件的路径,客户端类将从该文件中读取并清除内容。我在这里遇到了太多的访问冲突,所以想使用另一个类作为存储路径数据的方法。但是,我想知道,如果仍然存在问题,或者如果游戏类尝试调用存储类中的方法进行写入,而客户端类同时调用存储中的方法,结果会怎样类来阅读和清除。

【问题讨论】:

  • 您的应用程序是多线程还是多进程? (或两者都不)
  • 两件事怎么会同时发生?
  • @aioobe - @sinelaw 的问题值得一问。考虑到问题的措辞方式,OP 的“同时”概念可能与您和我的不同。

标签: java multithreading methods contention


【解决方案1】:

听起来您需要考虑线程和同步。我建议阅读“Java 并发实践”。

【讨论】:

  • +1 - 非常好的建议。多线程编程需要彻底了解您在做什么。否则,您最终会编写出偶尔以难以诊断的方式失败的应用程序。
【解决方案2】:

如果存在多个线程,您的类必须是thread safe。实现此目的的一种方法是使并发访问的方法synchronized

下面是一个让您入门的示例:

public class Test {

    public static void main(String[] args) throws Exception {
        new Thread() { public void run() { Test.method(); }}.start();
        new Thread() { public void run() { Test.method(); }}.start();
    }

    public synchronized static void method() {
        System.out.println("hello ");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {}
        System.out.println("world");
    }
}

如果没有 synchronized 修饰符,这个程序会打印出来

hello 
hello    
world
world

使用synchronized关键字,一次只能有一个线程调用method,从而程序打印

hello 
world
hello 
world

【讨论】:

    【解决方案3】:

    我假设您的两个类在不同的线程中运行,因此它们可能会同时访问第三个类。对他们正在读写的资源的访问需要同步(互斥)。 Java有关键字“synchronized”,可以多种方式使用,防止并发修改等,详见herehere

    【讨论】:

      【解决方案4】:

      理论上正确的答案是:“任何事情都有可能发生”。

      这两个调用可以一个接一个地运行,也可以相互交错,结果是不可预测的,并且可能是灾难性的。

      这就是为什么 Java 为您提供了几种处理它的方法。

      1. 最简单(听起来)的方法是编写线程安全的方法。实际上,这通常意味着您应该只使用局部变量,并且不得修改作为参数传递给您的对象。 (没有副作用。)许多方法自动属于这一类,在这种情况下您不必担心并发性。

      2. 如果您的方法不能成为线程安全的,您需要以某种方式处理并发调用。 synchronized 块是最常用的构造,但在某些情况下,volatile 字段或使用 Atomic* 类就足够了。但是这个主题太重了,无法在一个答案中涵盖,所以我建议你阅读the concurrency tutorial

      【讨论】:

      • “任何事情都可能发生”,- 并非如此,JLS 包含对 JVM 内存模型的非常具体的限制。
      • @aioobe 是的,而且绝对不会引起地震,我已经纠正了。
      猜你喜欢
      • 2011-03-14
      • 2019-11-03
      • 1970-01-01
      • 2014-03-18
      • 1970-01-01
      • 2012-05-31
      • 2019-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多