JavaRush /Kurslar /All lectures for UZ purposes /Synchronizers: ресурстарга киришни синхронизация қилиш Ja...

Synchronizers: ресурстарга киришни синхронизация қилиш Javaда

All lectures for UZ purposes
Daraja, Dars
Mavjud

Semaphore

Semaphoreлар, одатда, файл системаси билан ишлашда потоклар сонини чеклаш керак бўлганда ишлатилади. Файл ёки бошқа умумий ресурска кириш ҳисоблагич орқали бошқарилади. Агар унинг қиймати нолдан катта бўлса, кириш руҳсат этилган, лекин шу пайт ҳисоблагичнинг кўрсатгичлари камаяди.

Ҳисоблагич нольга қайтган пайтда, жорий поток бошқа поток ресурсни бўшатгунича блокланади. Руҳсатлар сони параметрини конструктор орқали белгилаш керак.

Бу параметрни сенинг компютер ёки ноутбукингнинг қувватига қараб индивидуал тарзда танлаш керак.


public class Main {

   public static void main(String[] args) {
       Semaphore sem = new Semaphore(1);
       CommonResource res = new CommonResource();
       new Thread(new MyThread(res, sem, "MyThread_1")).start();
       new Thread(new MyThread(res, sem, "MyThread_2")).start();
       new Thread(new MyThread(res, sem, "MyThread_3")).start();
   }
}

class CommonResource {
   int value = 0;
}

class MyThread implements Runnable {
   CommonResource commonResource;
   Semaphore semaphore;
   String name;
   MyThread(CommonResource commonResource, Semaphore sem, String name) {
       this.commonResource = commonResource;
       this.semaphore = sem;
       this.name = name;
   }

   public void run() {

       try {
           System.out.println(name + " руҳсатни кутяпти");
           semaphore.acquire();
           commonResource.value = 1;
           for (int i = 1; i < 7; i++) {
               System.out.println(this.name + ": " + commonResource.value);
               commonResource.value++;
               Thread.sleep(150);
           }
       } catch (InterruptedException e) {
           System.out.println(e.getMessage() + " " + name);
           Thread.currentThread().interrupt();
       }
       System.out.println(name + " руҳсатни бўшатяпти");
       semaphore.release();
   }
}

CountDownLatch ва бошқалар

CountDownLatch — бир неча потокларга бошқа потокларда бажарилаётган маълум операциялар тугашини кутушга имкон беради. Масалан, илова ўрнатишини тушунтириш мумкин: сен фойдаланиш шартларини қабул қилмагунча, янги дастур қайси папкага ўрнатилишини танламасанг илова ўрнатилишини бошламайди. Бунинг учун махсус countDown() усули бор — бу усул hisoblagichни камайтиради.

Ҳисоблагич нолга тенг бўлган пайтда, awaitда кутяётган барча потоклар ишини давом еттиради ва кейинги барча await чақирувлари кутмасдан ўтади. Hisoblagich бир марта фойдаланилади ва бошланғич ҳолатига қайта ўрнатилмайди.

CyclicBarrier — бир нуқтада белгиланган потоклар сонини ҳамоҳанглаштириш учун ишлатилади. Барьер вақтда N-потоклар await(...) усулини чақирганда ва блокланганда еришилади. Шу пайт ҳисоблагич бошланғич ҳолатига қайта ўрнатилади ва кутяётган потоклар бўшатилади. Қўшимча тарзда, потоклар блокланишидан ва ҳисоблагични қайта ўрнатишдан олдин махсус кодни ишга тушириш мумкин. Бу учун конструктор орқали Runnable интерфейсини ишга туширувчи объект узатилади.

Exchanger<V> — Exchanger класи потоклар орасида маълумот алмашинади. У типлаштирилган бўлиб, потоклар қандай маълумот туридан фойдаланиши кераклигини типлаштиради.

Маълумот алмашиниш бу класидаги ягона усул exchange() орқали амалга оширилади:


V exchange(V x) throws InterruptedException 
V exchange(V x, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException

x параметри алмашиниш учун маълумот буфери ҳисобланади. Усулнинг иккинчи формаси timeout — кутуш вақти ва unit — timeout параметри учун қўлланиладиган вақт бирликлари параметрларини ҳам аниқлайди.

Phaser класи потокларни умумий ҳаракатнинг алоҳида фазаси ёки босқичини кўрсатиш имконини беради. Phaser муайян фаза тугамагунча синхронизация объектни белгилайди. Кейин Phaser кейинги босқичга ўтиб, унинг тугашини яна кутади.

Phaser класи билан ишлаганда, одатда, унинг объекти аввало яратилади. Кейин барча иштирокчиларни рўйхатдан ўтказиш керак бўлади. Ҳар бир иштирокчи учун register() усули чақирилади ёки бу усулсиз ҳам Phaser конструкторига иштирокчилар сони берилса бўлади.

Шундан сўнг, ҳар бир иштирокчи муайян фазага тегишли бўлган бир нечта ҳаракатларни бажаради. А Phaser синхронизатори, барча иштирокчилар фаза ишини тугатмагунча кутушда бўлади. Фаза тугатилганини синхронизаторга хабар бериш учун иштирокчи arrive() ёки arriveAndAwaitAdvance() усулини чақириши керак. Шундан сўнг, синхронизатор кейинги фазага ўтиши мумкин.

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