Проблемы с многопоточностью
Есть код:
if(immortalityOn){
Log.d("immortalityOn", String.valueOf(immortalityOn));
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
immortalityOn = false;
}
}).start();
}
Переменной immortalityOn значение false должно присваиваться всегда спустя 7 секунд, после того, как ей было присвоено значение true. Но иногда этого ожидания не происходит и переменная сразу получает значение false
Доработанный вариант (который, правда, вообще вылетает, через несколько секунд после начала работы):
if(immortalityOn){
Log.d("immortalityOn", String.valueOf(immortalityOn));
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d("immortalityOn", String.valueOf(immortalityOn));
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
immortalityOn = false;
}
}, 7000);
}
}).start();
}
Вернулся к первоначальному варианту и сделал так, чтобы переменная, находящаяся в if (заключил в if другую переменную, вместо immortalityOn), меняла значение по нажатию кнопки, результат: меняю переменную на false, она ждёт 7 секунд, меняет значение immortalityOn на false, но после, когда переменная immortalityOn получает значение true, оно сразу меняется на false, без ожидания 7 секунд:
if(!soundOn){
Log.d("immortalityOn", String.valueOf(immortalityOn));
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
immortalityOn = false;
}
}).start();
}
Ответы (3 шт):
Попробуйте так. В данном случае содержимое метода run() выполнится через 7 секунд :
if(immortalityOn){
Log.d("immortalityOn", String.valueOf(immortalityOn));
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
immortalityOn = false;
}
}, 7000);
}
Если объявить immortalityOn как volatile не работает?
volatile boolean immortalityOn=true;
if(immortalityOn){
Log.d("immortalityOn", String.valueOf(immortalityOn));
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
immortalityOn = false;
}
}).start();
}
Мой вариант - при нажатии кнопки четко через 7 секунд меняется значение.
public class MainActivity extends AppCompatActivity {
private boolean immortalityOn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
button.setOnClickListener(view -> {
immortalityOn = true;
Log.d("MainActivity", "immortalityOn=" + immortalityOn);
if (immortalityOn)
setImmortality(false);
});
}
private void setImmortality(boolean value) {
Executor executor = Executors.newSingleThreadExecutor();
Handler handler = new Handler(Looper.getMainLooper());
executor.execute(() -> {
try {
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(() -> {
immortalityOn = value;
Log.d("MainActivity", "immortalityOn=" + immortalityOn);
});
});
}
}