2016-05-24 4 views
1

мне нужно помощь с некоторой теорией JAVA ...Синхронизированные методы и статические JAVA доступа к переменному/ANDROID

Так что я недавно обнаружил, что если приложение использует несколько потоков, и существует возможность различных потоков к тому же общей переменной в то же время, то следует использовать «синхронизированные» методы для получения/установки указанной переменной.

Так что ... в моем (местоположении) приложении, у меня есть переменные LAT и LON, которые принадлежат к MainActivity и являются статическими. Они доступны из справочных услуг, как так:

appendToPOST(MainActivity.LAT); 

И в самом MainActivity, я использую службу определения местоположения Google Play, и поэтому в) методе обратного вызова onLocationChanged (в MainActivity, у меня есть:

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() для использования синхронизированных методов, даже если он существует в том же классе, что и переменная?

+0

в основном вы правы, но 'multitThreading' имеют огромную тему, так как у вас есть« синхронизированные »методы в вашем случае (все методы), которые вы кодируете, его можно запустить в [DeadLock] (http://www.javaworld.com /article/2075692/java-concurrency/avoid-synchronization-deadlocks.html) – Hosseini

+0

@ Hosseini deadlocks не должны быть проблемой в данном примере, поскольку только один объект блокировки является классом 'MainActivity'. Либо нить держит этот объект блокировки, либо нет. Однако, если есть другие классы, которые используют синхронизацию также и с другими объектами блокировки, взаимоблокировки в конечном счете важны для рассмотрения. Как правило, можно сказать: если ваш код использует несколько разных объектов блокировки, эти объекты ** всегда ** должны быть приобретены в том же порядке. К сожалению, не всегда так легко обеспечить это правило ... – dpr

+0

здесь мы не видим ничего, кроме 'getter/setter', мы просто говорим, что это не каждый раз, когда нам нужно защищать' state' помещать его в ' синхронизированный'. – Hosseini

ответ

1

Ваши изменения верны. И как вы уже упоминали каждый доступ (локальный доступ также) к этим переменным общего состояния должен использовать синхронизированные аксессоры.

Кроме того, если значения LAT и LON принадлежат друг другу (я предполагаю, что вы представляете местоположение с этими значениями), вы должны убедиться, что они не могут быть изменены или извлечены независимо друг от друга. То есть вы не должны добавлять сеттер и 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. См. here для краткого введения объекта Lock.

UPDATE:
Обновленный ответ с кодом, например

2

Во-первых, synchronized static methods являются тип встроенных замков Java. Они используют объект класса как блокировку, поэтому только один поток за раз может работать с классом. Если один поток выполняет один из методов, другие потоки не могут выполнять какие-либо из методов объектов. Это блокировка типа синхронизации. Это влияет на производительность. Но если высокая производительность не требуется, это решение будет работать. Вам нужны методы маркировки, которые считывают/изменяют данные с помощью ключевого слова synchronized.

Во-вторых, я предполагаю, что ваши переменные означают координаты местоположения: широта и долгота. Если это так, к ним необходимо обратиться вместе. Вы можете создать новый составной класс.Если они не доступны одновременно, это может привести к состоянию гонки.

PS: сообщите нам, если синхронизация влияет на производительность. Существуют неблокирующие решения на уровне класса.

Смежные вопросы