JavaRush /Блоги Java /Random-TG /Шумо наметавонед Java-ро бо ришта вайрон кунед: Қисми VI ...
Viacheslav
Сатҳи

Шумо наметавонед Java-ро бо ришта вайрон кунед: Қисми VI - Ба монеа!

Дар гурӯҳ нашр шудааст

Муқаддима

Ҷараён як чизи ҷолиб аст. Дар баррасиҳои қаблӣ, мо ба баъзе аз абзорҳои мавҷуда барои татбиқи multithreading назар кардем. Биёед бубинем, ки мо боз чӣ чизҳои ҷолибро карда метавонем. Дар ин маврид мо бисёр чизро медонем. Масалан, аз " Шумо Java-ро бо ришта вайрон карда наметавонед: Қисми I - Threads ", мо медонем, ки ришта ришта аст. Мо медонем, ки ришта ягон вазифаро иҷро мекунад. Агар мо хоҳем, ки вазифаи мо иҷро карда тавонад ( run), пас мо бояд риштаро муайян кунем, то ки Runnable. Шумо наметавонед Java-ро бо ришта вайрон кунед: Қисми VI - Ба монеа!  - 1Барои дар хотир доштан, мо метавонем Tutorialspoint Java Online Compiler -ро истифода барем :
public static void main(String []args){
	Runnable task = () -> {
 		Thread thread = Thread.currentThread();
		System.out.println("Hello from " + thread.getName());
	};
	Thread thread = new Thread(task);
	thread.start();
}
Мо инчунин медонем, ки мо чунин мафҳум дорем, ки қулф. Мо дар ин бора дар " Шумо Java-ро бо ришта вайрон карда наметавонед: Қисми II - Синхронизатсия " мехонем. Ришта метавонад қулфро ишғол кунад ва сипас риштаи дигаре, ки қулфро ишғол карданӣ мешавад, маҷбур мешавад, ки то озод шудани қулф интизор шавад:
import java.util.concurrent.locks.*;

public class HelloWorld{
	public static void main(String []args){
		Lock lock = new ReentrantLock();
		Runnable task = () -> {
			lock.lock();
			Thread thread = Thread.currentThread();
			System.out.println("Hello from " + thread.getName());
			lock.unlock();
		};
		Thread thread = new Thread(task);
		thread.start();
	}
}
Ман фикр мекунам, ки вақти он расидааст, ки дар бораи он ки мо боз чӣ кор карда метавонем, ки ҷолиб аст.

Семафорҳо

Воситаи соддатарини назорат кардани чанд ришта дар як вақт кор кардан мумкин аст семафор аст. Мисли роҳи оҳан. Чароғи сабз фурӯзон аст - шумо метавонед. Чароғи сурх фурӯзон аст - мо интизорем. Мо аз семафор чӣ интизорем? Иҷозатҳо. Иҷозат ба забони англисӣ - иҷозат. Барои гирифтани иҷозат, шумо бояд онро ба даст оред, ки ба забони англисӣ гирифта мешавад. Ва ҳангоме ки иҷозат дигар лозим нест, мо бояд онро бидиҳем, яъне озод кунем ё аз он халос шавем, ки ба забони англисӣ озод мешавад. Биёед бубинем, ки он чӣ гуна кор мекунад. Мо бояд синфро ворид кунем java.util.concurrent.Semaphore. Мисол:
public static void main(String[] args) throws InterruptedException {
	Semaphore semaphore = new Semaphore(0);
	Runnable task = () -> {
		try {
			semaphore.acquire();
			System.out.println("Finished");
			semaphore.release();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	};
	new Thread(task).start();
	Thread.sleep(5000);
	semaphore.release(1);
}
Тавре ки мебинем, калимаҳои англисиро аз ёд карда, мо мефаҳмем, ки семафор чӣ гуна кор мекунад. Ҷолиб он аст, ки шарти асосӣ ин аст, ки "ҳисоб"-и семафор бояд шумораи мусбати иҷозатҳоро дошта бошад. Аз ин рӯ, шумо метавонед онро бо минус оғоз кунед. Ва шумо метавонед зиёда аз 1 дархост дархост кунед (харед).

Countdown Latch

Механизми навбатӣ ин аст CountDownLatch. Countdown дар забони англисӣ ақибшумор аст ва Латч болт ё қулф аст. Яъне, агар мо онро тарҷума кунем, пас ин як қулф бо ҳисоб аст. Дар ин ҷо ба мо воридоти мувофиқи синф лозим аст java.util.concurrent.CountDownLatch. Ин мисли мусобиқа ё мусобиқаест, ки ҳама дар хати аввал ҷамъ мешаванд ва вақте ҳама омодаанд, иҷозат дода мешавад ва ҳама дар як вақт оғоз мекунанд. Мисол:
public static void main(String[] args) {
	CountDownLatch countDownLatch = new CountDownLatch(3);
	Runnable task = () -> {
		try {
			countDownLatch.countDown();
			System.out.println("Countdown: " + countDownLatch.getCount());
			countDownLatch.await();
			System.out.println("Finished");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	};
	for (int i = 0; i < 3; i++) {
		new Thread(task).start();
 	}
}
интизор шудан бо забони англисӣ - интизор шудан. Яъне мо аввал гап мезанем countDown. Тавре ки Google Translator мегӯяд, ҳисобкунӣ "амали шумориши рақамҳо бо тартиби баръакс ба сифр" аст, яъне анҷом додани амали ақибшумор, ки ҳадафи он ҳисоб кардан то сифр аст. Ва он гоҳ мо мегӯем await- яъне интизор шавед, ки арзиши ҳисобкунак ба сифр табдил ёбад. Ҷолиб он аст, ки чунин ҳисобкунак якдафъаина аст. Тавре ки дар JavaDoc гуфта шудааст - "Вақте ки риштаҳо бояд бо ин роҳ такроран ҳисоб карда шаванд, ба ҷои он CyclicBarrier -ро истифода баред", яъне агар шумо ҳисобкунии такрорӣ лозим бошад, шумо бояд варианти дигареро истифода баред, ки CyclicBarrier.

CyclicBarrier

Тавре ки аз ном бармеояд, CyclicBarrierон як монеаи даврӣ аст. Мо бояд синфро ворид кунем java.util.concurrent.CyclicBarrier. Биёед як мисолро дида бароем:
public static void main(String[] args) throws InterruptedException {
	Runnable action = () -> System.out.println("На старт!");
	CyclicBarrier berrier = new CyclicBarrier(3, action);
	Runnable task = () -> {
		try {
			berrier.await();
			System.out.println("Finished");
		} catch (BrokenBarrierException | InterruptedException e) {
			e.printStackTrace();
		}
	};
	System.out.println("Limit: " + berrier.getParties());
	for (int i = 0; i < 3; i++) {
		new Thread(task).start();
	}
}
Тавре ки шумо мебинед, ришта иҷро шуда истодааст await, яъне интизор аст. Дар ин ҳолат, арзиши монеа кам мешавад. berrier.isBroken()Вақте ки ҳисоб ба сифр мерасад, монеа шикаста ҳисобида мешавад ( ). Барои аз нав барқарор кардани монеа, шумо бояд занг занед berrier.reset(), ки дар CountDownLatch.

Мубодилакунанда

Табобати навбатӣ ин аст Exchanger. Мубодила аз забони англисӣ ҳамчун мубодила ё мубодила тарҷума карда мешавад. A Exchangerивазкунанда аст, яъне чизест, ки тавассути он мубодила мекунанд. Биёед як мисоли оддиро бубинем:
public static void main(String[] args) {
	Exchanger<String> exchanger = new Exchanger<>();
	Runnable task = () -> {
		try {
			Thread thread = Thread.currentThread();
			String withThreadName = exchanger.exchange(thread.getName());
			System.out.println(thread.getName() + " обменялся с " + withThreadName);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	};
	new Thread(task).start();
	new Thread(task).start();
}
Дар ин ҷо мо ду риштаро оғоз мекунем. Ҳар яке аз онҳо усули мубодиларо иҷро мекунанд ва интизоранд, ки риштаи дигар низ усули мубодиларо иҷро кунад. Ҳамин тариқ, риштаҳо далелҳои гузаштаро байни худ иваз мекунанд. Чизи ҷолиб. Оё вай ба ту чизеро хотиррасон намекунад? Ва хотиррасон мекунад SynchronousQueue, ки дар дor cachedThreadPool'а. Барои равшанӣ, ин ҷо як мисол аст:
public static void main(String[] args) throws InterruptedException {
	SynchronousQueue<String> queue = new SynchronousQueue<>();
	Runnable task = () -> {
		try {
			System.out.println(queue.take());
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	};
	new Thread(task).start();
	queue.put("Message");
}
Мисол нишон медиҳад, ки бо кушодани риштаи нав ин ришта ба ҳолати интизорӣ мегузарад, зеро навбат холй мешавад. Ва он гоҳ mainришта матни "Паём" -ро дар навбат мегузорад. Дар айни замон, он барои вақти зарурӣ қатъ мешавад, то он даме, ки ин унсури матнро аз навбат қабул кунад. Дар ин мавзӯъ шумо инчунин метавонед хонед " SynchronousQueue Vs Exchanger ".

Фазер

Ва нихоят ширинтарин чиз — Phaser. Мо бояд синфро ворид кунем java.util.concurrent.Phaser. Биёед як мисоли оддиро бубинем:
public static void main(String[] args) throws InterruptedException {
        Phaser phaser = new Phaser();
        // Вызывая метод register, мы регистрируем текущий поток (main) How участника
        phaser.register();
        System.out.println("Phasecount is " + phaser.getPhase());
        testPhaser(phaser);
        testPhaser(phaser);
        testPhaser(phaser);
        // Через 3 секунды прибываем к барьеру и снимаемся регистрацию. Кол-во прибывших = кол-во регистраций = пуск
        Thread.sleep(3000);
        phaser.arriveAndDeregister();
        System.out.println("Phasecount is " + phaser.getPhase());
    }

    private static void testPhaser(final Phaser phaser) {
        // Говорим, что будет +1 участник на Phaser
        phaser.register();
        // Запускаем новый поток
        new Thread(() -> {
            String name = Thread.currentThread().getName();
            System.out.println(name + " arrived");
            phaser.arriveAndAwaitAdvance(); //threads register arrival to the phaser.
            System.out.println(name + " after passing barrier");
        }).start();
    }
Мисол нишон медиҳад, ки монеа ҳангоми истифодаи Phaser'a, вақте ки шумораи бақайдгирӣ бо шумораи воридшудагон ба монеа мувофиқат мекунад, вайрон мешавад. PhaserШумо метавонед маълумоти бештарро дар мақола аз маркази " New Phaser synchronizer " пайдо кунед .

Натиҷаҳо

Тавре ки шумо аз мисолҳо мебинед, роҳҳои гуногуни ҳамоҳангсозии риштаҳо мавҷуданд. Пештар ман кӯшиш мекардам, ки чизеро дар бораи мултипрединг дар ёд дошта бошам, умедворам, ки қисмҳои қаблӣ муфид буданд. Онҳо мегӯянд, ки роҳи чанд ришта аз китоби "Concurrency Java in Practice" оғоз мешавад. Гарчанде ки он дар соли 2006 нашр шуда буд, одамон ҷавоб медиҳанд, ки китоб хеле муҳим аст ва ҳоло ҳам пурқувват аст. Масалан, шумо метавонед муҳокимаҳоро дар ин ҷо хонед: " Оё ҳамзамон Java дар амал амал мекунад? ". Инчунин хондани истинодҳо аз муҳокима муфид аст. Масалан, истинод ба китоби " The Well-Grounded Java Developer " мавҷуд аст, ки дар он ба " Боби 4. Ҳамоҳангсозии муосир " таваҷҷӯҳ кардан лозим аст . Боз як барраси пурра дар ҳамон мавзӯъ вуҷуд дорад: " Оё ҳамкории Java дар амал то ҳол дар даврони java 8 муҳим аст ". Он инчунин маслиҳатҳоро дар бораи он, ки шумо бояд дар ҳақиқат дарк кардани мавзӯъ хонед. Пас аз он, шумо метавонед ба чунин як китоби олиҷаноб ба мисли " OCA OCP JavaSE 8 Tests Practice Programmer " нигаред . Мо ба қисми дуюм, яъне OCP таваҷҷӯҳ дорем. Ва дар "∫" санҷишҳо мавҷуданд. Ин китоб ҳам саволҳо ва ҳам ҷавобҳоро бо шарҳҳо дар бар мегирад. Масалан: Шумо наметавонед Java-ро бо ришта вайрон кунед: Қисми VI - Ба монеа!  - 3Бисёриҳо метавонанд мегӯянд, ки ин танҳо ёдгирии навбатии усулҳост. Аз як тараф, бале. Аз тарафи дигар, ба ин савол метавон бо дар хотир доштан посух дод, ки ExecutorServiceин як навъ "навсозӣ" аст Executor. Ва Executorон танҳо барои пинҳон кардани усули эҷоди риштаҳо пешбинӣ шудааст, аммо на роҳи асосии иҷрои онҳо, яъне кор дар риштаи нав Runnable. Бинобар ин, execute(Callable)не, зеро онҳо танҳо усулҳоеро илова карданд ExecutorService, ки метавонанд баргарданд . Тавре ки шумо мебинед, мо метавонем рӯйхати усулҳоро дар хотир нигоҳ дорем, аммо тахмин кардан осонтар аст, агар мо табиати худи синфҳоро донем. Хуб, баъзе маводи иловагӣ дар мавзӯъ: ExecutorsubmitFuture #Вячеслав
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION