JavaRush /Java blogi /Random-UZ /Multithreading: Thread klassi usullari nima qiladi

Multithreading: Thread klassi usullari nima qiladi

Guruhda nashr etilgan
Salom! Bugun biz multithreading haqida gapirishni davom ettiramiz. Keling, Thread sinfini va uning bir nechta usullari qanday ishlashini ko'rib chiqaylik. Ilgari, biz sinf usullarini o'rganganimizda, biz buni ko'pincha shunday yozar edik: "usul nomi" -> "u nima qiladi".
Multithreading: Thread sinfining usullari nima qiladi - 1
Bu Thread usullari bilan ishlamaydi :) Ularning mantig'i ancha murakkab va bir nechta misollarsiz tushunish mumkin emas.

Thread.start() usuli

Keling, takrorlashdan boshlaylik. Esingizda bo'lsa kerak, siz o'z sinfingizni sinfdan meros qilib olish Threadva undagi usulni bekor qilish orqali ip yaratishingiz mumkin run(). Lekin, albatta, bu o'z-o'zidan boshlanmaydi. Buning uchun biz ob'ektimizdagi usulni chaqiramiz start(). Multithreading: Thread sinfining usullari nima qiladi - 2Oldingi ma'ruzadagi misolni eslaylik:
public class MyFirstThread extends Thread {

   @Override
   public void run() {
       System.out.println("Выполнен поток " + getName());
   }
}


public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {
           MyFirstThread thread = new MyFirstThread();
           thread.start();
       }
   }
}
Iltimos, diqqat qiling: mavzuni boshlash uchun siz maxsus usulni chaqirishingiz kerakstart(),run()! Bu juda oson xato, ayniqsa multithreadingni birinchi marta o'rganayotganda. run()Agar bizning misolimizda 10 marta o'rnigaob'ekt usulini chaqirsangizstart(), natija quyidagicha bo'ladi:
public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {
           MyFirstThread thread = new MyFirstThread();
           thread.run();
       }
   }
}
Mavzu-0 mavzu bajarildi Mavzu-1 mavzu bajarildi Mavzu-2 mavzu bajarildi Mavzu-3 mavzu bajarildi Mavzu-4 mavzu bajarildi Mavzu-5 mavzu bajarildi Mavzu-6 mavzu bajarildi. Chiqish ketma-ketligiga qarang: hamma narsa qat'iy tartibda ketadi. G'alati, to'g'rimi? Biz bunga o'rganmaganmiz, chunki biz allaqachon bilamizki, iplarni ishga tushirish va bajarish tartibi bizning operatsion tizimimiz ichidagi super intellekt - mavzuni rejalashtiruvchi tomonidan belgilanadi. Balki omadim kelgandir? Albatta, bu omadga bog'liq emas. Buni dasturni yana bir necha marta ishga tushirish orqali tekshirishingiz mumkin. Gap shundaki, usulni to'g'ridan-to'g'ri chaqirishrun()multithreading bilan hech qanday aloqasi yo'q. Bunday holda, dastur asosiy ish zarrachasida - usul bajarilganda bajariladimain(). U shunchaki konsolga ketma-ket 10 ta satr chiqaradi va tamom. 10 ta mavzu boshlanmaydi. Shuning uchun kelajak uchun esda tuting va doimo o'zingizni tekshiring. Agar buni amalga oshirishni istasangizrun(), uni chaqiringstart(). Keling, davom etaylik.

Thread.sleep() usuli

Joriy oqimning bajarilishini biroz vaqtga to'xtatib turish uchun sleep(). Multithreading: Thread sinfining usullari nima qiladi - 3Usul sleep()parametr sifatida millisekundlar sonini, ya'ni ipni uyquga qo'yish kerak bo'lgan vaqtni oladi.
public class Main {

   public static void main(String[] args) throws InterruptedException {

       long start = System.currentTimeMillis();

       Thread.sleep(3000);

       System.out.println(" - Сколько я проспал? \n - " + ((System.currentTimeMillis()-start)) / 1000 + " секунды");

   }
}
Konsol chiqishi: - Men qancha vaqt uxladim? - 3 soniya Iltimos, diqqat qiling: usul sleep()statik: u joriy ipni uyqu rejimiga qo'yadi. Ya'ni, hozirda ishlayotgan. Yana bir muhim nuance: uyqu holatidagi oqim uzilishi mumkin. Bunday holda, dasturda istisno paydo bo'ladi InterruptedException. Quyida biz bir misolni ko'rib chiqamiz. Aytgancha, ip "uyg'onganidan" keyin nima bo'ladi? U to'xtagan joyidan darhol ijrosini davom ettiradimi? Yo'q. Mavzu uyg'onganidan so'ng - argument sifatida o'tgan vaqt tugashi bilan - u ishga tushadiganThread.sleep() holatga kiradi . Biroq, bu mavzu rejalashtiruvchisi uni ishga tushirishini anglatmaydi. Bu boshqa "uxlamaydigan" ipga ustunlik berishi mumkin va bizning "yangi uyg'ongan" ipimiz birozdan keyin ishlashni davom ettiradi. Esingizda bo'lsin: "uyg'onish o'sha soniyada ishlashni davom ettirishni anglatmaydi!"

Thread.join() usuli

Многопоточность: что делают методы класса Thread - 4Usul join()joriy ish zarrachasining bajarilishini boshqa ip tugaguncha to'xtatib turadi. Agar bizda 2 ta ip bo'lsa, t1va t2, va biz yozamiz -
t1.join()
t2t1 o'z ishini tugatmaguncha ish boshlamaydi. Usul join()iplarning bajarilish ketma-ketligini ta'minlash uchun ishlatilishi mumkin. join()Keling, misol yordamida ishni ko'rib chiqaylik :
public class ThreadExample extends Thread {

   @Override
   public void run() {

       System.out.println("Начало работы потока " + getName());

       try {
           Thread.sleep(5000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       System.out.println("Поток " + getName() +  " завершил работу.");
   }
}


public class Main {

   public static void main(String[] args) throws InterruptedException {

       ThreadExample t1 = new ThreadExample();
       ThreadExample t2 = new ThreadExample();

       t1.start();


 /*Второй поток t2 начнет выполнение только после того, How будет завершен
       (or бросит исключение) первый поток - t1*/
       try {
           t1.join();
       } catch (InterruptedException e) {
           e.printStackTrace();
       }

       t2.start();

       //Главный поток продолжит работу только после того, How t1 и t2 завершат работу
       try {
           t1.join();
           t2.join();
       } catch (InterruptedException e) {
           e.printStackTrace();
       }

       System.out.println("Все потоки закончor работу, программа завершена");

   }
}
Biz oddiy sinf yaratdik ThreadExample. Uning vazifasi ish boshlanishi haqida ekranda xabarni ko'rsatish, keyin 5 soniya davomida uxlab qolish va oxirida ish tugaganligi haqida xabar berishdir. Hech narsa murakkab emas. Asosiy mantiq sinfda mavjud Main. Sharhlarga qarang: usuldan foydalanib, join()biz iplarning bajarilish ketma-ketligini muvaffaqiyatli nazorat qilamiz. Mavzuning boshlanishini eslasangiz, mavzuni rejalashtiruvchi buni qildi. U ularni o'z xohishiga ko'ra ishga tushirdi: har safar boshqacha. Bu erda, usuldan foydalanib, biz birinchi navbatda ipning ishga tushirilishi va bajarilishini ta'minladik t1, keyin ip t2, va faqat ulardan keyin dasturni bajarishning asosiy oqimi. Davom etishga ruxsat. Haqiqiy dasturlarda siz ko'pincha ba'zi bir ipning bajarilishini to'xtatishingiz kerak bo'lgan vaziyatlarga duch kelasiz. Masalan, bizning ipimiz ishlamoqda, lekin u ma'lum bir hodisa yoki shartning bajarilishini kutmoqda. Agar bu sodir bo'lsa, u to'xtaydi. ga o'xshash usul mavjud bo'lsa, ehtimol mantiqiy bo'lar edi stop(). Biroq, hamma narsa juda oddiy emas. Bir vaqtlar Thread.stop()Java-da haqiqatda mavjud bo'lgan usul mavjud bo'lib, sizga ipning ishini to'xtatishga imkon beradi. Ammo keyinchalik u Java kutubxonasidan olib tashlandi. Siz uni Oracle hujjatlarida ko'rib chiqishingiz va u eskirgan deb belgilanganligini ko'rishingiz mumkin . Nega? Chunki u hech qanday qo'shimcha ish qilmasdan oqimni to'xtatdi. Masalan, ip ma'lumotlar bilan ishlashi va undagi biror narsani o'zgartirishi mumkin. stop()Keyin u ishning o'rtasida to'satdan nokautga uchradi - va shunday bo'ldi. To'g'ri o'chirish, resurslarni bo'shatish, hatto xatoliklarni bartaraf etish ham bo'lmadi - bularning hech biri sodir bo'lmadi. Usul stop(), mubolag'asiz, o'z yo'lidagi hamma narsani yo'q qildi. Uning ishlashini kimdir kompyuterni o'chirish uchun rozetkadan vilkasini qanday tortib olgani bilan solishtirish mumkin. Ha, siz kerakli natijaga erishishingiz mumkin. Ammo bir necha hafta ichida kompyuter buning uchun "rahmat" demasligini hamma tushunadi. Shu sababli, Java-da iplarni uzish mantig'i o'zgartirildi va endi maxsus usul qo'llaniladi - interrupt().

Thread.interrupt() usuli

Agar siz mavzudagi usulni interrupt() chaqirsangiz nima bo'ladi ? 2 ta variant mavjud:
  1. Agar ob'ekt o'sha paytda kutish holatida bo'lsa, masalan, joinyoki sleep, kutish to'xtatiladi va dastur InterruptedException.
  2. Agar ip o'sha paytda ishlaydigan holatda bo'lsa, ob'ektning mantiqiy bayrog'i o'rnatiladi interrupted.
Ammo biz ob'ektni ushbu bayroqning qiymatini tekshirishimiz va ishni o'zimiz to'g'ri bajarishimiz kerak! Shu maqsadda sinfda Threadmaxsus usul mavjud - boolean isInterrupted(). Keling, asosiy kurs ma'ruzasidan soat misoliga qaytaylik. Qulaylik uchun u biroz soddalashtirilgan:
public class Clock extends Thread {

   public static void main(String[] args) throws InterruptedException {
       Clock clock = new Clock();
       clock.start();

       Thread.sleep(10000);
       clock.interrupt();
   }

   public void run() {
       Thread current = Thread.currentThread();

       while (!current.isInterrupted())
       {
           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               System.out.println("Работа потока была прервана");
               break;
           }
           System.out.println("Tik");
       }
   }
}
Bizning holatlarimizda soat har soniyada boshlanadi va boshlanadi. 10-sekundda biz soat oqimini to'xtatamiz. Siz allaqachon bilganingizdek, agar biz to'xtatmoqchi bo'lgan mavzu kutish holatlaridan birida bo'lsa, bu natijaga olib keladi InterruptedException. Ushbu turdagi istisnolar tekshirilgan istisno hisoblanadi, shuning uchun uni osongina qo'lga olish va dasturni tugatish mantig'ini bajarish mumkin. Biz shunday qildik. Natijamiz quyidagicha: Tik Tik Tik Tik Tik Tik Tik Tik Tik Tik Tik Tik Tik Tik Tik Tik Tik Tik Tik mavzu ishi to'xtatildi.Bu bizning sinfning asosiy usullariga kirishimizni yakunlaydi Thread. O'z bilimlaringizni mustahkamlash uchun siz ko'p oqim haqida ushbu video ma'ruzani ko'rishingiz mumkin:
u ajoyib qo'shimcha material bo'lib xizmat qiladi! Oxirida, usullarni ko'rib chiqqandan so'ng, u kursda keyingi bosqichdan o'tishimizni aniq aytadi :) Omad tilaymiz!
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION