【问题标题】:Synchronized methods and static variable access JAVA / ANDROID同步方法和静态变量访问 JAVA / ANDROID
【发布时间】:2016-09-21 03:37:36
【问题描述】:

我需要一些 JAVA 理论方面的帮助...

所以我最近发现,如果一个应用程序使用多个线程,并且不同线程有可能同时访问同一个共享变量,那么应该使用“同步”方法来获取/设置所述变量。

所以...在我的(位置感知)应用程序中,我有变量 LAT 和 LON 属于 MainActivity 并且是静态的。它们是从后台服务访问的,如下所示:

appendToPOST(MainActivity.LAT);

在 MainActivity 本身中,我使用的是 google play 位置服务,因此在 MainActivity 的 onLocationChanged() 回调方法中,我有:

LAT = [arbitrary Double value goes here];

因此,这意味着我应该实施:

public static synchronized void setLAT(Double inLAT){

    LAT = inLAT;

}

public static synchronized void setLON(Double inLON){

    LON = inLON;

}

public static synchronized Double getLAT(){

    return LAT;

}

public static synchronized Double getLON(){

    return LON;

}

对吗?感谢您的任何澄清/帮助。

补充:另外,我是否应该更改 onLocationChanged() 方法中的代码以使用同步方法,即使它与变量存在于同一个类中?

【问题讨论】:

  • 在基本方面你是正确的,但multitThreading 有很大的话题,因为你有synchronized 方法在你的情况下(所有方法)你编码它可以运行到DeadLock
  • @Hosseini 死锁在给定示例中应该不是问题,因为MainActivity 类只有一个锁对象。线程是否持有此锁对象。但是,如果有其他类也与其他锁对象一起使用同步,那么死锁绝对是需要考虑的重要事项。根据经验,可以说:如果您的代码使用多个不同的锁对象,则需要以相同的顺序获取这些对象总是。不幸的是,确保这条规则并不总是那么容易......
  • 我们在这里看不到任何东西而不是getter/setter,我们只是说这不是每次我们需要保护state时都将其放入synchronized

标签: java android methods static synchronized


【解决方案1】:

首先,synchronized static methods 是 Java 的内置锁类型。他们使用类对象作为锁,因此一次只有一个线程可以使用该类。如果一个线程执行其中一种方法,则其他线程无法执行任何对象方法。这是锁定类型的同步。它影响性能。但是,如果不需要高性能,则此解决方案将起作用。您需要使用 synchronized 关键字来标记读取/更改数据的方法。

其次,我假设您的变量表示位置坐标:纬度和经度。如果是这样,它们必须一起访问。您可以制作新的复合类。如果没有同时访问它们,可能会导致竞争条件。

PS:让我们知道同步是否会影响性能。有类级别的非锁定解决方案。

【讨论】:

    【解决方案2】:

    到目前为止,您的更改是正确的。正如您已经提到的,对这些共享状态变量的每个访问(以及本地访问)都必须使用同步访问器。

    此外,如果LATLON 的值属于一起(我假设您用这些值表示一个位置),您应该确保它们不能相互独立地修改或检索。也就是说,您不应该为每个值添加一个 setter 和 getter,而是为两个值添加一个。如果这些值属于一起,您可以考虑引入一个代表这两个值的新类,例如

    public class Location {
        private double mLon;
        private double mLat;
    
        // Add getters and setters. These don't need to be synchronized
    }
    

    并将MainActivity 中的同步访问器更改为

    public static synchronized setLocation(final Location inLocation) {
        ...
    }
    

    为了完整性,使用synchronized 块可能是在共享状态对象上实现线程同步的最常见但不是最有效的解决方案。如果谈到性能,您可能应该看看java.util.concurrent 中的类。有关Lock 对象的简短介绍,请参阅here

    更新
    用代码示例更新答案

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-22
      • 2012-06-29
      • 2011-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多