Как упомянул @DavisHerring в комментарии, это (почти полностью) из-за пропущенных миллис в MyRunnable.run()
.Ваш код предполагает, что цикл будет «видеть» совершенно последовательные возвращаемые значения из System.currentTimeMillis()
.
Возможно, вы рассуждали, что поскольку цикл работает на полной скорости, он, несомненно, сможет вызвать System.currentTimeMillis()
многораз каждую миллисекунду, и поэтому вряд ли что-либо будет пропущено.Но тогда у вас больше потоков, чем у ядер, поэтому очевидно, что некоторые потоки должны тратить часть своего времени на вытеснение.
Кроме того, в любой приоритетной многозадачной операционной системе нет никакой гарантии, что какой-то конкретный поток будетвыполняется в любое конкретное время.
Таким образом, если данный поток прекращает выполнение на короткое время, он может легко пропустить кратное 50. Например, один из потоков может «увидеть» следующие возвращаемые значенияиз System.currentTimeMillis()
:
1546215544594
1546215544594
1546215544594
1546215544594 <-- thread is unscheduled here, causing a 23ms gap
1546215544617
1546215544617
1546215544617
1546215544617
ПРЕДЛАГАЕМОЕ ИСПРАВЛЕНИЕ
Вместо того, чтобы пытаться поймать каждую милли, возьмите время взломать в начале.Затем просто сделайте progress
равным (истекшее время) / 50:
progress = (int) ((System.currentTimeMillis() - hack) / 50);
bar.setProgress(progress);
В качестве отступления: System.currentTimeMillis()
не гарантирует возврат монотонно увеличивающегося результата (см. System.uptimeTimeMillis()
для альтернативы),но для вашей конкретной проблемы это, вероятно, не такая большая проблема.