Можно ли объявить что-то вроде этого?
static volatile boolean first=false;
Можно ли объявить что-то вроде этого?
static volatile boolean first=false;
Развернуть комментарий Майкла.
static
просто означает, что он не связан с экземпляром содержащего класса.
volatile
просто означает, что значение может быть изменено другими потоками без предупреждения.
Итак, ваш вопрос сводится к "может ли поле, не связанное с экземпляром содержащего класса, изменяться другим потоком без предупреждения?"
Как отметил Майкл, ответ на этот вопрос - да. Комбинация экземпляров ортогональна одновременной модификации.
Да, вы можете.
A static
переменная в Java хранится один раз для каждого класса (не один раз для объекта, например, нестатические переменные). Это означает, что все ваши объекты (и статические методы) имеют одну и ту же переменную.
Объявление переменной как volatile
(будь то static
или нет) указывает, что к переменной часто обращаются несколько потоков. В Java это сводится к тому, чтобы проинструктировать потоки, что они не могут кэшировать значение переменной, но должны будут сразу написать после мутации, чтобы другие потоки увидели изменение. (Потоки в Java могут свободно кэшировать переменные по умолчанию).
Конечно. Эффекты двух модификаторов полностью ортогональны.
да, вы можете.
static boolean first=false;
Когда вы объявляете статическую переменную, для всех объектов будет только одна копия, независимо от того, сколько объектов класса создано. Каждый поток будет иметь свою собственную кэшированную копию.
Если он изменчив, Thread должен каждый раз заходить в память и получать обновленное значение переменной.
static volatile boolean first=false;
Это будет
заставлять поток каждый раз читать память непосредственно
сначала найти значение переменной.
Что касается вопроса, да, мы можем, но в этом случае нам нужно обработать весь сценарий.
Получите доступ к статическому значению через несколько потоков, каждый поток может иметь свою локальную кешированную копию! Чтобы избежать этого, вы можете объявить переменную как static volatile, и это заставит поток читать каждый раз глобальное значение. Однако volatile не заменяет правильную синхронизацию
private static volatile int cnt = 0;
private void checkCnt() {
cnt+= 1;
// some conditions
// some code
cnt -= 1;
}
Одновременное выполнение checkCnt много раз окончательное значение cnt отличается от того, что мы ожидаем! Чтобы решить эту проблему, мы реализуем блокировку для отслеживания увеличения/уменьшения.
private static final Object lock = new Object();
private static volatile int cnt= 0;
private void checkCnt() {
synchronized (lock) {
cnt += 1;
}
//some conditions
//some code
synchronized (lock) {
cnt -= 1;
}
}
Не уверен, что это правильный путь, но этим мы можем управлять вещами и использовать статические с volatile. Пожалуйста, предоставьте информацию, если есть лучший способ.