JavaRush /Kurslar /All lectures for UZ purposes /newCachedThreadPool Metodi

newCachedThreadPool Metodi

All lectures for UZ purposes
Daraja, Dars
Mavjud

Yana bir turdagi oqimlar havzasi - keshlangan. Bu oqimlar havzalari ham xuddi qayd etilganlar kabi keng qo'llaniladi.

Oqimlar havzasi oqimlarni keshlaydi, shuning uchun nomlanishi shunday. U oqimlarni (lekin ishlatilmayotganini) o'z vaqtida faol ravishda saqlaydi, bu oqimlardan yangi vazifalarni bajarishda foydalanish uchun. Bunday oqimlar havzasini eng yaxshi ishlatish tavsiya etiladi, agar bizda bajarish uchun ma'lum bir me'yorda yengil vazifalar bo'lsa.

“Ma'lum bir me'yordan” tushunish ancha keng bo'lishi mumkin, lekin bunday havza har bir vazifalar soniga mos kelmasligini tushunish kerak. Masalan, biz millionta vazifa yaratmoqchi bo'lsak, ular juda kam vaqt oladigan bo'lsa-da, baribir, resurslarni nojo'ya ishlatamiz va ishlashni yomonlashtiramiz. Shuningdek, biz bunday havzadan foydalanishdan qochishimiz kerak, agar bajarish vaqti oldindan aytilmagan bo'lsa, masalan, kiritish-chiqarish vazifalarida.

“Kaput” ostida quyidagi parametrlarga ega ThreadPoolExecutor konstruktor chaqiriladi:


public static ExecutorService newCachedThreadPool() {
    // Boshqa kodlar
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, 
      new SynchronousQueue<Runnable>());
}

Konstruktor uchun quyidagi parametrlar beriladi:

Parametr Qiymat
corePoolSize (qanday oqimlar miqdori executor xizmati boshida tayyor (ishga tushirilgan) bo'ladi) 0
maximumPoolSize (Eng ko'p oqimlar miqdori, qaysini executor xizmat yaratishi mumkin) Integer.MAX_VALUE
keepAliveTime (Bo'shagan oqim qancha vaqt yashaydi va keyinroq yo'q qilinadi, agar oqimlar soni corePoolSize dan ortiq bo'lsa) 60L
unit (Vaqt birliklari) TimeUnit.SECONDS
workQueue (Navbatni amalga oshirish) new SynchronousQueue<Runnable>()

Biz ham ThreadFactory turidagi o'zimizning amalga oshirgan obyektimizni parametr sifatida berishimiz mumkin.

SynchronousQueue haqida gaplashamiz

Sinxron uzatishning asosiy g'oyasi juda sodda va ayni paytda intuitiv emas (bu hissiyot, sog'lom fikr yoki his-tuyg'ularga asoslanib baholanganida haqiqiy ko'rinmaydi): elementni faqat boshqa oqim bu elementni bir vaqtning o'zida qabul qilayotganda navbatga qo'yish mumkin. Boshqacha aytganda, sinxron navbat ichida vazifalar bo'la olmaydi, chunki yangi vazifa kelganda, bajaruvchi oqim allaqachon bu vazifani olishadi.

Yangi vazifa navbatga kelganda, agar havzada bo'sh faol oqim mavjud bo'lsa, u bu vazifani oladi, agar barcha oqimlar band bo'lsa - yangi oqim yaratiladi.

Keshlangan havza nol oqimdan boshlanadi va potentsial ravishda Integer.MAX_VALUE ga teng oqimlar sonigacha o'sishi mumkin. Keshlangan oqimlar havzasi uchun deyarli yagona cheklov tizim resurslaridir.

Tizim resurslarini boshqarish uchun keshlangan oqimlar havzalari bir daqiqa davomida ishdan turgan oqimlarni yo'q qiladi.

Keling, buni amalda qanday ishlashini tekshiramiz. Biz vazifa klasi yaratamiz, foydalanuvchi so'rovini modellashtiramiz:


public class Task implements Runnable {
   int taskNumber;
   
   public Task(int taskNumber) {
       this.taskNumber = taskNumber;
   }
   
   @Override
   public void run() {
       System.out.println("Foydalanuvchi so'rovi №" + taskNumber + " oqimda qayta ishlangan " + Thread.currentThread().getName());
   }
}
    

main da biz newCachedThreadPool yaratamiz va 3ta vazifani bajarishga qo'shamiz. Bu yerda xizmatimizning statusini chiqaramiz (1).

Keyin 30 soniyaga pauza qilamiz, shundan so'ng yana bir vazifani bajarishga qo'yib, statusni chiqaramiz (2).

Bundan keyin asosiy oqimimizni 70 soniyaga to'xtatamiz, statusni chiqaramiz (3) va yana 3ta vazifani bajarishga qo'shamiz va statusni yana chop etamiz (4).

Vazifalarni qo'shgandan keyin, statuslar chiqariladigan joylarda, biz sleep ni 1 soniyaga qo'yamiz, aniq chiqish uchun.


ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 3; i++) {
            executorService.submit(new Task(i));
        } 

        TimeUnit.SECONDS.sleep(1);
            System.out.println(executorService);	//(1)
        
        TimeUnit.SECONDS.sleep(30);
        
        executorService.submit(new Task(3));
        TimeUnit.SECONDS.sleep(1);
            System.out.println(executorService);	//(2)

        TimeUnit.SECONDS.sleep(70);
        
            System.out.println(executorService);	//(3)
        
        for (int i = 4; i < 7; i++) {
            executorService.submit(new Task(i));
        }  
        
        TimeUnit.SECONDS.sleep(1);
            System.out.println(executorService);	//(4)
        executorService.shutdown();

Shunday qilib, natija:

Foydalanuvchi so'rovi №0 oqimda qayta ishlangan pool-1-thread-1
Foydalanuvchi so'rovi №1 oqimda qayta ishlangan pool-1-thread-2
Foydalanuvchi so'rovi №2 oqimda qayta ishlangan pool-1-thread-3
(1) java.util.concurrent.ThreadPoolExecutor@f6f4d33[Running, pool size = 3, active threads = 0, queued tasks = 0, completed tasks = 3]
Foydalanuvchi so'rovi №3 oqimda qayta ishlangan pool-1-thread-2
(2) java.util.concurrent.ThreadPoolExecutor@f6f4d33[Running, pool size = 3, active threads = 0, queued tasks = 0, completed tasks = 4]
(3) java.util.concurrent.ThreadPoolExecutor@f6f4d33[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 4]
Foydalanuvchi so'rovi №4 oqimda qayta ishlangan pool-1-thread-4
Foydalanuvchi so'rovi №5 oqimda qayta ishlangan pool-1-thread-5
Foydalanuvchi so'rovi №6 oqimda qayta ishlangan pool-1-thread-4
(4) java.util.concurrent.ThreadPoolExecutor@f6f4d33[Running, pool size = 2, active threads = 0, queued tasks = 0, completed tasks = 7]

Har bir qadamni tahlil qilamiz:

Qadam Tushuntirish
1 (3ta vazifa bajargandan keyin) 3ta oqim yaratildi, bu uchta oqimda 3ta vazifa bajarildi.
Status chiqarilganda, barcha 3ta vazifa bajarilgan bo'ladi va oqimlar boshqa vazifalarni bajarishga tayyor.
2 (30 soniya pauzadan keyin va yana bir vazifa bajargandan keyin) 30 soniya faoliyat bo'lmaganidan keyin oqimlar hali ham tirik va vazifalarni kutyapti.
Yana bir vazifa qo'shiladi va qolgani tirik oqimlar havzasidagi oqimda bajariladi.
Havzada yangi oqim ko'rinmaydi.
3 (70 soniya pauza o'rgandan keyin) Oqimlar havzadan olib tashlandi.
Vazifalarni qabul qilishga tayyor oqimlar yo'q.
4 (yana 3ta vazifa bajargandan keyin) Yana vazifalar bajarishga qo'shilganida, yangi oqimlar yaratildi, bu safar umumiy ikkita oqim 3ta vazifani bajarishga ulgurdi.

Shu tariqa, biz oqimlarni boshqarish bilan yana bir turdagi xizmat bilan tanishdik.

Executors sinfining boshqa yordamchi metodlariga o'xshash, newCachedThreadPool metodining ham o'z variantlari bor, qaysi parametr sifatida ThreadFactory turidagi obyektni qabul qiladi.

Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION