Как да забавим изпълнението на кода в Java

1. Въведение

Относително често се случва Java програми да добавят забавяне или пауза в своята работа. Това може да бъде полезно за темпото на задачите или за пауза на изпълнението, докато друга задача не завърши.

Този урок ще опише два начина за прилагане на закъснения в Java.

2. Подход, основан на нишка

Когато се изпълнява програма Java, тя поражда процес, който се изпълнява на хост машината. Този процес съдържа поне една нишка - основната нишка - в която се изпълнява програмата. Освен това Java позволява многопоточност, която позволява на приложенията да създават нови нишки, които работят паралелно или асинхронно на основната нишка.

2.1. Използване на Thread.sleep

Бърз и мръсен начин за пауза в Java е да кажете на текущата нишка да спи за определен период от време. Това може да се направи с помощта на Thread.sleep (милисекунди) :

try { Thread.sleep(secondsToSleep * 1000); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); }

Добра практика е методът за заспиване да се увива в блок try / catch, в случай че друга нишка прекъсне спящата нишка. В този случай ние хващаме InterruptException и изрично прекъсваме текущата нишка, така че тя може да бъде уловена по-късно и обработена. Това е по-важно в многонишковата програма, но все пак добра практика в еднонишковата програма, в случай че добавим други нишки по-късно.

2.2. Използване на TimeUnit.sleep

За по-добра четливост можем да използваме TimeUnit.XXX.sleep (y) , където XXX е времевата единица за заспиване ( СЕКУНДИ , МИНУТИ и т.н.), а y е броят на тази единица за спане. Това използва Thread.sleep зад кулисите. Ето пример за синтаксиса на TimeUnit :

try { TimeUnit.SECONDS.sleep(secondsToSleep); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); }

Има обаче някои недостатъци при използването на тези методи, базирани на нишки :

  • Времето за заспиване не е точно точно, особено когато се използват по-малки стъпки от време като милисекунди и наносекунди
  • Когато се използва вътре в цикли, сънят ще се отклони леко между итерациите на цикъла поради друго изпълнение на код, така че времето за изпълнение може да стане неточно след много итерации

3. Подход, основан на изпълнителна услуга

Java предоставя интерфейс ScheduledExecutorService , който е по-стабилно и прецизно решение. Този интерфейс може да насрочи кода да се изпълни веднъж след определено закъснение или на фиксирани интервали от време.

За да стартираме парче код веднъж след закъснение, можем да използваме метода на графика :

ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); executorService.schedule(Classname::someTask, delayInSeconds, TimeUnit.SECONDS);

Частта на Classname :: someTask е мястото, където указваме метода, който ще се изпълнява след закъснението:

  • someTask е името на метода, който искаме да изпълним
  • Име на класа е името на класа, който съдържа someTask метода

За да изпълним задача на фиксирани интервали от време, можем да използваме метода scheduleAtFixedRate :

ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); executorService.scheduleAtFixedRate(Classname::someTask, 0, delayInSeconds, TimeUnit.SECONDS);

Това ще извиква многократно метода someTask , като прави пауза за delayInSeconds между всяко обаждане.

Освен че позволява повече опции за синхронизиране, методът ScheduledExecutorService дава по-точни интервали от време, тъй като предотвратява проблеми с дрейфа.

4. Заключение

В тази статия обсъдихме два метода за създаване на закъснения в Java програми.

Пълният код за тази статия може да бъде намерен в Github. Това е проект, базиран на Maven, така че трябва да е лесно да се импортира и да се изпълнява както е.