Существует поток, который отслеживает новые электронные письма, пока статическая переменная tracking истинна. Это выглядит так:
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
tracking = true;
while(tracking){
//check emails
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
Я реализовал функцию остановки отслеживания электронных писем, которая в основном устанавливает для tracking значение false.
Отслеживание - это просто private static boolean, который я использую только внутри класса, который выполняет эти задачи.
Может ли такой подход привести меня к какой-либо проблеме?




Если есть несколько потоков, которые читают и записывают в одну и ту же переменную, вам необходимо использовать синхронизацию (например, AtomicBoolean). В этом конкретном случае достаточно объявить tracking как volatile, чтобы новое значение, установленное для этой переменной в одном потоке, было правильно видно в другом потоке:
private static volatile boolean tracking;
Can this approach lead me to any problem?
Да, оно может.
Вы столкнулись с проблемой «видимости». На самом высоком уровне «видимость» - это способность вашего потока видеть изменения, выполняемые другими потоками. Если вы хотите добиться наглядности, то, согласно спецификации Java, вам необходимо установить связь «происходит до» между считыванием значения и записью значения. Без такой связи нет гарантии, что любая запись в переменную tracking будет видна любым другим потоком, кроме того, который выполнил запись.
В вашем случае на ум приходят две возможности установить отношения «произошло до»:
volatile при его объявлении (никаких дальнейших изменений в вашей программе не требуется)AtomicBoolean (затем вы можете объявить его final и либо использовать tracking.set(false), чтобы отключить отслеживание, либо tracking.get(), чтобы проверить, следует ли еще отслеживать).Для ясности: не нужно выполнять оба изменения, это одно или другое.
Другие возможности включают в себя: защиту чтения и записи с помощью java.util.Lock, но это перебор.
Вы можете прочитать больше здесь: Как понять, что происходит, прежде чем последовать
Если это поток Только, использующий tracking, и вы просто используете его как способ завершить этот единственный поток, тогда с вами, вероятно, все будет в порядке, хотя это все еще сомнительно. Когда вы устанавливаете для tracking значение false, он может повторяться еще несколько раз, но в конечном итоге он будет читать false (если где-то не будет возвращено значение true, как описано ниже), и он завершится.
Но если есть несколько потоков, которые используют tracking, это определенно может быть проблемой для вас, даже если вы использовали volatile или AtomicBoolean.
Если вы установили tracking на false, но сразу после этого другой из ваших Runnable начинает работать и устанавливает для tracking значение true,
public void run() {
try {
tracking = true; // <-- sets tracking back to true
while(tracking){
//check emails
}
тогда потоки, которые вы пытались завершить, не прекратятся, поскольку tracking снова верен.
Вам нужно будет убедиться, что все потоки правильно остановлены, прежде чем снова установить для tracking значение true. В этом могут помочь синхронизация и блокировки.
Согласны с тем, что без дополнительных гарантий относительно того, когда и как запускаются потоки и сбрасывается переменная отслеживания, вы можете столкнуться с этой проблемой «поверх» / независимо от «проблем с видимостью».