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

Шумо наметавонед Java-ро бо ришта вайрон кунед: Қисми II - ҳамоҳангсозӣ

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

Муқаддима

Ҳамин тавр, мо медонем, ки дар Java риштаҳо мавҷуданд, ки шумо метавонед дар баррасии " Шумо Java-ро бо ришта вайрон карда наметавонед: Қисми I - Threads " хонда метавонед. Риштаҳо барои ҳамзамон кор кардан лозиманд. Аз ин рӯ, эҳтимоли зиёд вуҷуд дорад, ки риштаҳо бо ягон роҳ бо ҳам амал мекунанд. Биёед бифаҳмем, ки ин чӣ гуна рӯй медиҳад ва мо чӣ гуна назорати асосӣ дорем. Шумо наметавонед Java-ро бо ришта вайрон кунед: Қисми II - ҳамоҳангсозӣ - 1

Ҳамоиш

Усули Thread.yield() пурасрор аст ва хеле кам истифода мешавад. Дар Интернет вариантҳои зиёди тавсифи он мавҷуданд. То он дараҷае, ки баъзеҳо дар бораи як навъ навбати риштаҳо менависанд, ки дар он ришта бо назардошти афзалиятҳои онҳо поён меравад. Касе менависад, ки ришта мақоми худро аз давидан ба иҷрошаванда иваз мекунад (гарчанде ки ба ин статусҳо тақсимот вуҷуд надорад ва Java байни онҳо фарқ намекунад). Аммо дар асл, ҳама чиз хеле номаълум ва ба як маъно соддатар аст. Шумо наметавонед Java-ро бо ришта вайрон кунед: Қисми II - ҳамоҳангсозӣ - 2Дар мавзӯи ҳуҷҷатгузории усулҳо yieldхатогӣ мавҷуд аст " JDK-6416721: (риштаи мушаххас) Fix Thread.yield() javadoc ". Агар шумо онро хонед, возеҳ аст, ки дар асл ин усул yieldтанҳо ба нақшаи риштаи Java тавсия медиҳад, ки ба ин ришта вақти камтари иҷро дода шавад. Аммо воқеан чӣ мешавад, оё нақшасоз тавсияро мешунавад ва дар маҷмӯъ чӣ кор хоҳад кард, аз татбиқи JVM ва системаи оператсионӣ вобаста аст. Ё шояд аз баъзе омилҳои дигар. Ҳама нофаҳмиҳо эҳтимолан аз нав дида баромадани бисёр риштаҳо ҳангоми таҳияи забони Java ба амал омадаанд. Шумо метавонед бештар дар баррасии " Муқаддимаи мухтасари Java Thread.yield() " хонед.

Хоб - риштаи хоб рафтан

Ришта метавонад ҳангоми иҷрои он хоб кунад. Ин соддатарин намуди муомила бо риштаҳои дигар аст. Системаи амалиётӣ, ки дар он мошини виртуалии Java насб шудааст, ки дар он рамзи Java иҷро карда мешавад, нақшаи риштаи худро дорад, ки Thread Scheduler ном дорад. Маҳз ӯ қарор медиҳад, ки кадом риштаро кай гузаронад. Барномасоз наметавонад бо ин нақшакаш мустақиман аз codeи Java муошират кунад, аммо вай метавонад тавассути JVM аз нақшакаш хоҳиш кунад, ки риштаро барои муддате таваққуф кунад ва онро "хоб кунад". Шумо метавонед маълумоти бештарро дар мақолаҳои " Thread.sleep() " ва " Чӣ тавр кор мекунад Multithreading " хонед. Илова бар ин, шумо метавонед фаҳмед, ки риштаҳо дар ОС Windows чӣ гуна кор мекунанд: " Дохorи Windows Thread ". Акнун мо онро бо чашмони худ мебинем. Биёед рамзи зеринро дар файл захира кунем HelloWorldApp.java:
class HelloWorldApp {
    public static void main(String []args) {
        Runnable task = () -> {
            try {
                int secToWait = 1000 * 60;
                Thread.currentThread().sleep(secToWait);
                System.out.println("Waked up");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        Thread thread = new Thread(task);
        thread.start();
    }
}
Тавре ки шумо мебинед, мо вазифае дорем, ки 60 сония интизор аст ва пас аз он барнома ба итмом мерасад. Мо тартиб медиҳем javac HelloWorldApp.javaва иҷро мекунем java HelloWorldApp. Беҳтар аст, ки дар равзанаи алоҳида оғоз кунед. Масалан, дар Windows он чунин хоҳад буд: start java HelloWorldApp. Бо истифода аз фармони jps, мо PID-и равандро пайдо мекунем ва рӯйхати риштаҳоро бо истифода аз: мекушоем jvisualvm --openpid pidПроцесса: Шумо наметавонед Java-ро бо ришта вайрон кунед: Қисми II - ҳамоҳангсозӣ - 3Тавре ки шумо мебинед, риштаи мо ба ҳолати хоб ворид шудааст. Дар асл, хобидани риштаи ҷорӣ метавонад зеботар анҷом дода шавад:
try {
	TimeUnit.SECONDS.sleep(60);
	System.out.println("Waked up");
} catch (InterruptedException e) {
	e.printStackTrace();
}
Шумо эҳтимол пай бурдед, ки мо дар ҳама ҷо коркард мекунем InterruptedException? Биёед бифаҳмем, ки чаро.

Қатъи ришта ё Thread.interrupt

Гап дар сари он аст, ки дар ҳоле ки ришта дар хоб интизор аст, касе метавонад ба ин интизорӣ халал расонад. Дар ин ҳолат мо чунин истисноро ҳал мекунем. Ин пас аз он ки усул Thread.stopДепретатсия эълон карда шуд, анҷом дода шуд, яъне. кӯҳна ва барои истифода номатлуб. Сабаби ин дар он буд, ки ҳангоми даъват кардани усул stopришта танҳо "кушта шудааст", ки хеле пешгӯинашаванда буд. Мо наметавонистем бидонем, ки ҷараён кай қатъ мешавад, мо мувофиқати маълумотро кафолат дода наметавонем. Тасаввур кунед, ки шумо маълумотро ба файл менависед ва он гоҳ ҷараён нобуд мешавад. Аз ин рӯ, онҳо тасмим гирифтанд, ки маҷроро накуштан, балки огоҳ кардан лозим аст, ки онро қатъ кардан лозим аст. Чӣ гуна ба ин вокуниш ба худи ҷараён вобаста аст. Тафсилоти бештарро дар Oracle пайдо кардан мумкин аст " Чаро Thread.stop бекор карда шудааст? " Биёед як мисолро дида бароем:
public static void main(String []args) {
	Runnable task = () -> {
		try {
			TimeUnit.SECONDS.sleep(60);
		} catch (InterruptedException e) {
			System.out.println("Interrupted");
		}
	};
	Thread thread = new Thread(task);
	thread.start();
	thread.interrupt();
}
Дар ин мисол, мо 60 сонияро интизор намешавем, балки дарҳол 'Катлустан' -ро чоп мекунем. Ин аз он сабаб аст, ки мо усули риштаро номида будем interrupt. Ин усул "парчами дохorро бо номи ҳолати қатъ" муқаррар мекунад. Яъне, ҳар як ришта парчами дохилӣ дорад, ки мустақиман дастрас нест. Аммо мо усулҳои аслии муошират бо ин парчам дорем. Аммо ин ягона роҳ нест. Ришта метавонад дар раванди иҷро бошад, на интизори чизе, балки танҳо иҷро кардани амалҳо. Аммо он метавонад таъмин кунад, ки онҳо мехоҳанд онро дар як нуқтаи муайяни кори худ анҷом диҳанд. Барои намуна:
public static void main(String []args) {
	Runnable task = () -> {
		while(!Thread.currentThread().isInterrupted()) {
			//Do some work
		}
		System.out.println("Finished");
	};
	Thread thread = new Thread(task);
	thread.start();
	thread.interrupt();
}
Дар мисоли боло, шумо мебинед, ки ҳалқа whileто даме ки ришта аз берун қатъ карда шавад, кор мекунад. Чизи муҳиме, ки дар бораи парчами isInterrupted донист , ин аст, ки агар мо онро дастгир кунем InterruptedException, парчам isInterruptedаз нав барқарор мешавад ва он гоҳ isInterruptedон бардурӯғ бармегардад. Инчунин дар синфи Thread усули статикӣ мавҷуд аст, ки танҳо ба риштаи ҷорӣ дахл дорад - Thread.interrupted() , аммо ин усул парчамро ба бардурӯғ аз нав танзим мекунад! Муфассалтар дар боби " Катъи ришта " хонда метавонед .

Ҳамроҳ шудан — Мунтазири анҷоми риштаи дигар

Соддатарин намуди интизорӣ интизори анҷоми риштаи дигар аст.
public static void main(String []args) throws InterruptedException {
	Runnable task = () -> {
		try {
			TimeUnit.SECONDS.sleep(5);
		} catch (InterruptedException e) {
			System.out.println("Interrupted");
		}
	};
	Thread thread = new Thread(task);
	thread.start();
	thread.join();
	System.out.println("Finished");
}
Дар ин мисол, риштаи нав 5 сония хоб хоҳад кард. Дар баробари ин риштаи асосй мунтазир мешавад, ки риштаи хобида аз хоб бедор шуда, корашро ба охир расонад. Агар шумо тавассути JVisualVM назар кунед, ҳолати ришта чунин хоҳад буд: Шумо наметавонед Java-ро бо ришта вайрон кунед: Қисми II - ҳамоҳангсозӣ - 4Бо шарофати асбобҳои назорат, шумо метавонед бубинед, ки бо ришта чӣ рӯй медиҳад. Ин усул joinхеле содда аст, зеро он танҳо як усул бо codeи java аст, ки waitҳангоми зинда будани риштае, ки дар он номида мешавад, иҷро мешавад. Вақте ки ришта мемирад (дар қатъ), интизорӣ қатъ карда мешавад. Ин тамоми ҷодугарии усул аст join. Аз ин рӯ, биёед ба қисми ҷолибтарин гузарем.

Монитор консепсия

Дар multithreading чунин чизе ба монанди Monitor вуҷуд дорад. Умуман, калимаи монитор аз лотинӣ ҳамчун “нозир” ё “нозир” тарҷума шудааст. Дар доираи ин мақола, мо кӯшиш мекунем, ки моҳиятро ба ёд орем ва барои онҳое, ки мехоҳанд, ман аз шумо хоҳиш мекунам, ки ба мавод аз истинодҳо барои тафсилот ғарқ шавед. Биёед саёҳати худро бо мушаххасоти забони Java оғоз кунем, яъне бо JLS: " 17.1. Синхронизатсия ". Дар он чунин гуфта мешавад: Шумо наметавонед Java-ро бо ришта вайрон кунед: Қисми II - ҳамоҳангсозӣ - 5Маълум мешавад, ки Java барои ҳамоҳангсозии байни риштаҳо механизми муайянеро бо номи "Монитор" истифода мебарад. Ҳар як an object дорои мониторе мебошад, ки бо он алоқаманд аст ва риштаҳо метавонанд онро қулф кунанд ё кушоянд. Баъдан, мо дар вебсайти Oracle дастури омӯзишӣ хоҳем ёфт: " Қулфҳои дохилӣ ва синхронизатсия ". Ин дастур мефаҳмонад, ки синхронизатсия дар Java дар атрофи як сохтори дохилӣ сохта шудааст, ки ҳамчун қулфи дохилӣ ё қулфи монитор маъруф аст. Аксар вақт чунин қулфро танҳо "монитор" меноманд. Мо инчунин бори дигар мебинем, ки ҳар як an object дар Java қулфи дохилӣ дорад, ки бо он алоқаманд аст. Шумо метавонед " Java - Қулфҳо ва Синхронизатсияи дохилӣ " -ро хонед. Баъдан, фаҳмидан муҳим аст, ки чӣ гуна an object дар Java метавонад бо монитор алоқаманд бошад. Ҳар як an object дар Java дорои сарлавҳа аст - як намуди метамаълумоти дохилӣ, ки барои барномасоз аз code дастрас нест, аммо мошини виртуалӣ барои дуруст кор кардан бо an objectҳо лозим аст. Сарлавҳаи an object дорои MarkWord мебошад, ки чунин менамояд: Шумо наметавонед Java-ро бо ришта вайрон кунед: Қисми II - ҳамоҳангсозӣ - 6

https://edu.netbeans.org/contrib/slides/java-overview-and-java-se6.pdf

Мақолаи Ҳабр дар ин ҷо хеле муфид аст: " Аммо чанд ришта чӣ гуна кор мекунад? Қисми I: ҳамоҳангсозӣ ." Ба ин мақола тавсифи мухтасари блоки вазифаҳо аз bugtaker JDK илова кардан лозим аст: " JDK-8183909 ". Шумо метавонед ҳамин чизро дар " JEP-8183909 " хонед. Ҳамин тавр, дар Java, монитор бо an object алоқаманд аст ва ришта метавонад ин риштаро маҳкам кунад ё онҳо инчунин мегӯянд, ки "қуфл гиред". Мисоли соддатарин:
public class HelloWorld{
    public static void main(String []args){
        Object object = new Object();
        synchronized(object) {
            System.out.println("Hello World");
        }
    }
}
Ҳамин тавр, бо истифода аз калимаи калидӣ, synchronizedриштаи ҷорӣ (дар он ин сатрҳои code иҷро карда мешаванд) кӯшиш мекунад, ки монитори бо an object алоқамандро истифода барад objectва "қуфл гиред" ё "мониторро забт кунед" (варианти дуюм ҳатто беҳтар аст). Агар барои монитор ягон ихтилоф вуҷуд надошта бошад (яъне ҳеҷ каси дигар намехоҳад дар ҳамон an object ҳамоҳанг созад), Java метавонад кӯшиш кунад, ки оптимизатсияро бо номи "қуфлкунии ғаразнок" иҷро кунад. Сарлавҳаи an object дар Mark Word дорои теги мувофиқ ва сабти риштаи он аст, ки монитор ба он пайваст карда шудааст. Ин хароҷотро ҳангоми гирифтани монитор кам мекунад. Агар монитор қаблан ба риштаи дигар пайваст шуда бошад, пас ин қулф кофӣ нест. JVM ба намуди навбатии қулфкунӣ мегузарад - қулфи асосӣ. Он амалиёти муқоиса ва иваз (CAS) -ро истифода мебарад. Ҳамзамон, сарлавҳа дар Mark Word дигар худи Mark Word-ро нигоҳ намедорад, аммо истинод ба нигаҳдории он + барчасп иваз карда мешавад, то JVM фаҳмад, ки мо қулфи асосиро истифода мебарем. Агар барои монитор аз якчанд ришта ихтилоф вуҷуд дошта бошад (яке мониторро гирифтааст ва дуюмӣ мунтазири баровардани монитор аст), он гоҳ тег дар Mark Word тағир меёбад ва Mark Word ба нигоҳ доштани истинод ба монитор ҳамчун an object - як ҷузъи дохorи JVM. Тавре ки дар JEP гуфта шудааст, дар ин ҳолат, барои нигоҳ доштани ин an object дар минтақаи хотираи Native Heap ҷой лозим аст. Истинод ба макони нигаҳдории ин сохтори дохилӣ дар an objectи Mark Word ҷойгир карда мешавад. Ҳамин тариқ, тавре мебинем, монитор воқеан як механизми таъмини ҳамоҳангсозии дастрасии якчанд риштаҳо ба захираҳои муштарак мебошад. Якчанд амалисозии ин механизм мавҷуданд, ки JVM байни онҳо мегузаранд. Аз ин рӯ, барои содда, ҳангоми сухан дар бораи монитор, мо воқеан дар бораи қуфлҳо гап мезанем. Шумо наметавонед Java-ро бо ришта вайрон кунед: Қисми II - ҳамоҳангсозӣ - 7

Ҳамоҳангсозӣ ва интизори қулф

Мафҳуми монитор, тавре ки мо қаблан дидем, бо мафҳуми «блоки синхронизатсия» (ё тавре ки онро низ меноманд, бахши муҳим) зич алоқаманд аст. Биёед як мисолро дида бароем:
public static void main(String[] args) throws InterruptedException {
	Object lock = new Object();

	Runnable task = () -> {
		synchronized (lock) {
			System.out.println("thread");
		}
	};

	Thread th1 = new Thread(task);
	th1.start();
	synchronized (lock) {
		for (int i = 0; i < 8; i++) {
			Thread.currentThread().sleep(1000);
			System.out.print("  " + i);
		}
		System.out.println(" ...");
	}
}
Дар ин чо риштаи асосй аввал супоришро ба риштаи нав мефиристад ва баъд дархол кулфро «забт мекунад» ва бо он амалиёти тулонй ичро мекунад (8 сония). Ҳамаи ин вақт, вазифа наметавонад ба блок барои иҷрои он ворид шавад synchronized, зеро қуфл аллакай ишғол шудааст. Агар ришта қулфро ба даст наорад, он дар монитор онро интизор мешавад. Ҳамин ки онро қабул мекунад, иҷроишро идома медиҳад. Вақте ки ришта аз монитор берун мешавад, қулфро мебарорад. Дар JVisualVM он чунин хоҳад буд: Шумо наметавонед Java-ро бо ришта вайрон кунед: Қисми II - ҳамоҳангсозӣ - 8Тавре ки шумо мебинед, вазъ дар JVisualVM "Монитор" номида мешавад, зеро ришта баста шудааст ва мониторро ишғол карда наметавонад. Шумо инчунин метавонед ҳолати риштаро дар code фаҳмед, аммо номи ин ҳолат бо шартҳои JVisualVM мувофиқат намекунад, гарчанде ки онҳо ба ҳам монанданд. Дар ин ҳолат, th1.getState()давра BLOCKED -роfor бармегардонад , зеро Ҳангоми кор кардани ҳалқа, мониторро ришта ишғол мекунад ва ришта баста мешавад ва то баргардонидани қулф корашро идома дода наметавонад. Илова ба блокҳои ҳамоҳангсозӣ, тамоми усулро ҳамоҳанг кардан мумкин аст. Масалан, усул аз синф : lockmainth1HashTable
public synchronized int size() {
	return count;
}
Дар як воҳиди вақт ин усул танҳо бо як ришта иҷро карда мешавад. Аммо ба мо қуфл лозим аст, дуруст? Бале, ба ман лозим аст. Дар мавриди усулҳои an object, қулф хоҳад буд this. Дар ин мавзӯъ баҳси ҷолибе вуҷуд дорад: " Оё бартарии истифодаи усули синхронӣ ба ҷои блоки ҳамоҳангшуда вуҷуд дорад? ". Агар усул статикӣ бошад, пас қулф нест this(зеро барои усули статикӣ вуҷуд дошта наметавонад this), балки an objectи синф (Масалан, Integer.class).

Интизор шавед ва дар монитор интизор шавед. Ҳамаи усулҳои огоҳӣ ва огоҳӣ

Thread боз як усули интизорӣ дорад, ки ба монитор пайваст аст. Баръакси sleepва join, онро танҳо номидан мумкин нест. Ва номи ӯ аст wait. waitИн усул дар an objectе иҷро карда мешавад, ки мо мехоҳем дар монитораш интизор шавем. Биёед як мисолро бубинем:
public static void main(String []args) throws InterruptedException {
	    Object lock = new Object();
	    // task будет ждать, пока его не оповестят через lock
	    Runnable task = () -> {
	        synchronized(lock) {
	            try {
	                lock.wait();
	            } catch(InterruptedException e) {
	                System.out.println("interrupted");
	            }
	        }
	        // После оповещения нас мы будем ждать, пока сможем взять лок
	        System.out.println("thread");
	    };
	    Thread taskThread = new Thread(task);
	    taskThread.start();
        // Ждём и после этого забираем себе лок, оповещаем и отдаём лок
	    Thread.currentThread().sleep(3000);
	    System.out.println("main");
	    synchronized(lock) {
	        lock.notify();
	    }
}
Дар JVisualVM он чунин хоҳад буд: Шумо наметавонед Java-ро бо ришта вайрон кунед: Қисми II - ҳамоҳангсозӣ - 10Барои фаҳмидани он ки ин чӣ гуна кор мекунад, шумо бояд дар хотир доред, ки усулҳо waitба . Аҷиб ба назар мерасад, ки усулҳои марбут ба ришта дар . Аммо ҷавоб дар ин ҷост. Тавре ки мо дар хотир дорем, ҳар як an object дар Java сарлавҳа дорад. Сарлавҳа дорои маълумоти гуногуни хидматрасонӣ, аз ҷумла маълумот дар бораи монитор—маълумот дар бораи ҳолати басташавӣ мебошад. Ва тавре ки мо дар хотир дорем, ҳар як an object (яъне ҳар як мисол) бо як an objectи дохorи JVM бо номи қулфи дохилӣ робита дорад, ки онро монитор низ меноманд. Дар мисоли боло, вазифа тавсиф мекунад, ки мо блоки ҳамоҳангсозиро дар мониторе, ки бо . Агар дар ин монитор қулф гирифтан имконпазир бошад, пас . Риштае, ки ин вазифаро иҷро мекунад мониторро озод мекунад , аммо ба навбати риштаҳое, ки интизори огоҳинома дар монитор мебошанд, ҳамроҳ мешавад . Ин навбати риштаҳо WAIT-SET номида мешавад, ки моҳиятро дурусттар инъикос мекунад. Ин бештар аз як қатор аст. Ришта бо вазифаи вазифа риштаи нав эҷод мекунад, онро оғоз мекунад ва 3 сония интизор мешавад. Ин имкон медиҳад, ки бо эҳтимолияти баланди риштаи нав қулфро пеш аз ришта гирифта , дар монитор навбат гузорад. Пас аз он худи ришта ба блоки синхронизатсия ворид мешавад ва дар монитор огоҳиномаро дар бораи ришта иҷро мекунад. Пас аз фиристодани огоҳинома, ришта мониторро озод мекунад ва риштаи нав (ки қаблан интизор буд) пас аз интизории баровардани монитор иҷроро идома медиҳад. Имкон дорад, ки огоҳинома танҳо ба яке аз риштаҳо ( ) ё ба ҳамаи риштаҳои навбатӣ якбора ( ). Шумо метавонед маълумоти бештарро дар " Фарқият байни notify() ва notifyAll() дар Java " хонед. Бояд қайд кард, ки тартиби огоҳӣ аз татбиқи JVM вобаста аст. Шумо метавонед маълумоти бештарро дар " Чӣ гуна бояд бо огоҳӣ ва огоҳӣ аз гуруснагӣ ҳал кард? ". Синхронизатсияро бе нишон додани an object иҷро кардан мумкин аст. Инро вақте иҷро кардан мумкин аст, ки на қисмати алоҳидаи code, балки тамоми усул ҳамоҳанг карда мешавад. Масалан, барои усулҳои статикӣ қулф an objectи синф хоҳад буд (ба воситаи ): notifyjava.lang.ObjectObjectlockwaitlocklockmainmainmainlockmainlocklocknotifynotifyAll.class
public static synchronized void printA() {
	System.out.println("A");
}
public static void printB() {
	synchronized(HelloWorld.class) {
		System.out.println("B");
	}
}
Дар робита ба истифодаи қулфҳо, ҳарду усулҳо якхелаанд. Агар усул статикӣ набошад, синхронизатсия мувофиқи ҷараёни ҷорӣ instance, яъне мувофиқи this. Воқеан, мо қаблан гуфта будем, ки бо истифода аз усул getStateшумо метавонед мақоми риштаро ба даст оред. Ҳамин тавр, дар ин ҷо риштае ҳаст, ки аз ҷониби монитор дар навбат гузошта шудааст, ҳолати интизорӣ ё TIMED_WAITING хоҳад буд, агар усул waitмаҳдудияти вақти интизориро муайян кунад. Шумо наметавонед Java-ро бо ришта вайрон кунед: Қисми II - ҳамоҳангсозӣ - 11

Давраи ҳаёти ришта

Чи хеле ки дидем, чараён дар рафти хаёт макоми худро дигар мекунад. Дар асл, ин дигаргуниҳо давраи ҳаёти ришта мебошанд. Вақте ки ришта нав сохта мешавад, он мақоми НАВ дорад. Дар ин мавқеъ, он ҳанӯз оғоз нашудааст ва Java Thread Scheduler ҳанӯз дар бораи риштаи нав чизе намедонад. Барои он ки банақшагирии ришта дар бораи ришта огоҳ шавад, шумо бояд ба thread.start(). Сипас ришта ба ҳолати RUNNABLE мегузарад. Дар Интернет бисёр схемаҳои нодуруст мавҷуданд, ки дар онҳо ҳолати Runnable ва Running ҷудо карда шудаанд. Аммо ин хато аст, зеро... Java байни статусҳои "тайёр ба кор" ва "давидан" фарқ намекунад. Вақте ки ришта зинда аст, аммо фаъол нест (иҷрошаванда нест), он дар яке аз ду ҳолат аст:
  • Блокшуда - интизори ворид шудан ба қисмати муҳофизатшуда, яъне. ба synchonizedблок.
  • ИНТИЗОР - риштаи дигарро дар асоси шарт интизор аст. Агар шарт дуруст бошад, барномасози ришта риштаро оғоз мекунад.
Агар ришта бо вақт интизор бошад, он дар ҳолати TIMED_WAITING аст. Агар ришта дигар кор накунад (бомуваффақият анҷом дода шавад ё ба истиснои ҳолатҳо), он ба ҳолати ХАТМАН дода мешавад. Барои фаҳмидани ҳолати ришта (ҳолати он) усул истифода мешавад getState. Риштаҳо инчунин усуле доранд isAlive, ки агар ришта қатъ нашуда бошад, ҳақиқиро бармегардонад.

LockSupport ва таваққуфгоҳи ришта

Аз Java 1.6 як механизми ҷолиб бо номи LockSupport мавҷуд буд . Шумо наметавонед Java-ро бо ришта вайрон кунед: Қисми II - ҳамоҳангсозӣ - 12Ин синф "иҷозат" ё иҷозатро бо ҳар як риштае, ки онро истифода мебарад, алоқаманд мекунад. Даъвати усул parkфавран бармегардад, агар иҷозат мавҷуд бошад, ки ҳамон иҷозатро дар давоми занг ишғол мекунад. Дар акси ҳол, он баста мешавад. Занг задан ба усул unparkиҷозат медиҳад, агар он аллакай дастрас набошад. Танҳо 1 иҷозат вуҷуд дорад.Дар API API, LockSupportяк Semaphore. Биёед як мисоли оддиро бубинем:
import java.util.concurrent.Semaphore;
public class HelloWorldApp{

    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(0);
        try {
            semaphore.acquire();
        } catch (InterruptedException e) {
            // Просим разрешение и ждём, пока не получим его
            e.printStackTrace();
        }
        System.out.println("Hello, World!");
    }
}
Ин рамз то абад интизор мешавад, зеро семафор ҳоло 0 иҷозат дорад. Ва ҳангоме ки бо code даъват карда мешавад acquire(яъне, иҷозат талаб кунед), ришта то гирифтани иҷозат интизор мешавад. Азбаски мо интизор ҳастем, мо вазифадорем, ки онро коркард кунем InterruptedException. Ҷолиб он аст, ки семафор ҳолати риштаи алоҳидаро амалӣ мекунад. Агар мо ба JVisualVM назар кунем, мебинем, ки давлати мо Интизор нест, балки Парк аст. Шумо наметавонед Java-ро бо ришта вайрон кунед: Қисми II - ҳамоҳангсозӣ - 13Биёед ба мисоли дигар назар кунем:
public static void main(String[] args) throws InterruptedException {
        Runnable task = () -> {
            //Запаркуем текущий поток
            System.err.println("Will be Parked");
            LockSupport.park();
            // Как только нас распаркуют - начнём действовать
            System.err.println("Unparked");
        };
        Thread th = new Thread(task);
        th.start();
        Thread.currentThread().sleep(2000);
        System.err.println("Thread state: " + th.getState());

        LockSupport.unpark(th);
        Thread.currentThread().sleep(2000);
}
Ҳолати ришта ИНТИЗОР хоҳад буд, аммо JVisualVM waitаз synchronizedва parkаз LockSupport. Чаро ин қадар муҳим аст LockSupport? Биёед бори дигар ба Java API муроҷиат кунем ва ба ҳолати Thread WAITING назар кунем . Тавре ки шумо мебинед, танҳо се роҳи ворид шудан ба он вуҷуд дорад. 2 роҳ - ин waitва join. Ва сеюм аст LockSupport. Қулфҳо дар Java дар ҳамон принсипҳо сохта шудаанд LockSupportва асбобҳои сатҳи баландро ифода мекунанд. Биёед кӯшиш кунем, ки якеро истифода барем. Биёед, масалан, дар ReentrantLock:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class HelloWorld{

    public static void main(String []args) throws InterruptedException {
        Lock lock = new ReentrantLock();
        Runnable task = () -> {
            lock.lock();
            System.out.println("Thread");
            lock.unlock();
        };
        lock.lock();

        Thread th = new Thread(task);
        th.start();
        System.out.println("main");
        Thread.currentThread().sleep(2000);
        lock.unlock();
    }
}
Мисли мисолҳои қаблӣ, дар ин ҷо ҳама чиз оддӣ аст. lockмунтазири он аст, ки касе захираеро нашр кунад. Агар мо дар JVisualVM назар кунем, мо мебинем, ки риштаи нав то он даме, ки mainришта ба он қулф медиҳад, таваққуф карда мешавад. Шумо метавонед маълумоти бештарро дар бораи қулфҳо дар ин ҷо бихонед: " Барномасозии чанд ришта дар Java 8. Қисми дуюм. Ҳамоҳангсозии дастрасӣ ба an objectҳои тағирёбанда " ва " Java Lock API. Назария ва намунаи истифода ." Барои беҳтар фаҳмидани татбиқи қулфҳо, муфид аст, ки дар бораи Phazer дар шарҳи " Синфи Phaser " хонед. Ва сухан дар бораи синхронизаторҳои гуногун, шумо бояд мақоларо дар Habré хонед " Java.util.concurrent.* Reference Synchronizers ".

Ҳамагӣ

Дар ин барраси, мо роҳҳои асосии мутақобилаи риштаҳоро дар Java дида баромадем. Маводи иловагӣ: #Вячеслав
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION