JavaRush /Блоги Java /Random-TG /Multithreading дар Java: моҳият, афзалиятҳо ва домҳои уму...

Multithreading дар Java: моҳият, афзалиятҳо ва домҳои умумӣ

Дар гурӯҳ нашр шудааст
Салом! Пеш аз ҳама, табрик мекунем: шумо ба мавзӯи Multithreading дар Java расидед! Ин му-ваффакияти чиддй аст, дар пеш аст. Аммо омода шавед: ин яке аз мавзӯъҳои душвортарин дар курс аст. Гап дар сари он нест, ки дар ин чо дарсдои мураккаб ва ё усулдои бисьёре истифода мешаванд: баръакс, ду дазордо дам нестанд. Ин бештар аз он аст, ки шумо бояд каме тафаккури худро тағир диҳед. Пештар, барномаҳои шумо пай дар пай иҷро мешуданд. Баъзе сатрҳои code ба дигарон пайравӣ мекарданд, баъзе усулҳо ба дигарон пайравӣ мекарданд ва дар маҷмӯъ ҳама чиз равшан буд. Аввалан, чизеро ҳисоб кунед, пас натиҷаро дар консол намоиш диҳед, пас барномаро қатъ кунед. Барои фаҳмидани чанд ришта, беҳтар аст, ки дар робита бо ҳамзамон фикр кунед. Биёед бо чизи хеле содда оғоз кунем :) Multithreading дар Java: моҳият, афзалиятҳо ва домҳои умумӣ - 1Тасаввур кунед, ки оилаи шумо аз як хона ба хонаи дигар мекӯчанд. Қисми муҳими ҳаракат ин бастабандии китобҳост. Шумо китобҳои зиёде ҷамъ кардаед ва шумо бояд онҳоро ба қуттиҳо гузоред. Ҳоло танҳо шумо озодед. Модар хӯрок омода мекунад, бародар либос ҷамъ мекунад ва хоҳар ба мағоза рафт. Дар танҳоӣ шумо метавонед ҳадди аққал идора кунед ва дер ё зуд шумо ҳатто ин вазифаро худатон анҷом медиҳед, аммо ин вақти зиёдро мегирад. Бо вуҷуди ин, пас аз 20 дақиқа хоҳарат аз мағоза бармегардад ва дигар коре надорад. Пас вай метавонад ба шумо ҳамроҳ шавад. Вазифа бетағйир монд: китобҳоро ба қуттиҳо гузоред. Он танҳо ду маротиба тезтар кор мекунад. Чаро? Зеро кор дар баробари ба чо оварда мешавад. Ду "риштаи" гуногун (шумо ва хоҳари шумо) дар як вақт як вазифаро иҷро мекунанд ва агар ҳеҷ чиз тағир наёбад, фарқияти вақт дар муқоиса бо вазъияте, ки шумо ҳама чизро танҳо мекунед, хеле калон хоҳад буд. Агар бародари шумо вазифаи худро зудтар анҷом диҳад, ӯ метавонад ба шумо кӯмак кунад ва корҳо боз ҳам тезтар пеш мераванд.

Проблемаҳое, ки чанд ришта дар Java ҳал мекунанд

Аслан, Java multithreading барои ҳалли ду мушкилоти асосӣ ихтироъ шудааст:
  1. Якчанд амалҳоро дар як вақт иҷро кунед.

    Дар мисоли дар боло овардашуда риштаҳои гуногун (яъне аъзоёни оила) якчанд амалро дар як вақт иҷро мекарданд: зарфҳоро шуста, ба мағоза рафтанд, чизҳоро печонд.

    Мисоли бештар «барномасоз»-ро овардан мумкин аст. Тасаввур кунед, ки шумо як барнома бо интерфейси корбар доред. Вақте ки тугмаи Continue пахш карда мешавад, бояд дар дохor барнома баъзе ҳисобҳо сурат гиранд ва корбар бояд экрани интерфейси зеринро бубинад. Агар ин амалҳо пайдарпай анҷом дода шаванд, пас аз пахш кардани тугмаи "Идома" барнома танҳо ях мекунад. Истифодабаранда ҳамон экранро бо тугмаи "Идома додан" мебинад, то он даме, ки ҳама ҳисобҳои дохилӣ ба анҷом расад ва барнома ба қисмате мерасад, ки интерфейс ба кашидани он оғоз мешавад.

    Хуб, биёед якчанд дақиқа интизор шавем!

    Multithreading дар Java: моҳият, афзалиятҳо ва домҳои умумӣ - 3

    Мо инчунин метавонем барномаи худро аз нав таҳия кунем ё, тавре ки барномасозон мегӯянд, "параллелизатсия" кунем. Бигзор ҳисобҳои зарурӣ дар як ришта анҷом дода шаванд ва интерфейс дар дигар. Аксари компютерҳо барои ин захираҳои кофӣ доранд. Дар ин ҳолат, барнома "беақл" нахоҳад буд ва корбар оромона дар байни экранҳои интерфейс ҳаракат мекунад, бидуни хавотирӣ аз он чӣ дар дохor он рӯй медиҳад. Ин халал намерасонад :)

  2. Ҳисобкуниро суръат диҳед.

    Дар ин ҷо ҳама чиз хеле соддатар аст. Агар протсессори мо якчанд ядро ​​дошта бошад ва аксари протсессорҳо ҳоло бисёраслӣ бошанд, рӯйхати вазифаҳои моро дар баробари якчанд ядроҳо ҳал кардан мумкин аст. Аён аст, ки агар мо бояд 1000 масъаларо ҳал кунем ва ҳар яки онҳо дар як сония ҳал карда шаванд, як ядро ​​дар 1000 сония, ду ядро ​​дар 500 сония, се ядро ​​дар тӯли 333 сония ва ғайра аз ӯҳдаи ин рӯйхат мебарояд.

Аммо, тавре ки шумо аллакай дар лексия хондаед, системаҳои муосир хеле оқилонаанд ва ҳатто дар як ядрои ҳисоббарорӣ онҳо метавонанд параллелизм ё псевдопараллелизмро амалӣ кунанд, вақте ки вазифаҳо бо навбат иҷро мешаванд. Биёед аз чизҳои умумӣ ба чизҳои мушаххас гузарем ва бо синфи асосӣ дар китобхонаи Java, ки ба чанд ришта алоқаманд аст - java.lang.Thread шинос шавем. Ба таври қатъӣ гӯем, риштаҳо дар Java бо мисолҳои синф муаррифӣ мешаванд Thread. Яъне барои сохтани 10 ришта ба шумо 10 an objectи ин синф лозим мешавад. Биёед мисоли соддатаринро нависед:
public class MyFirstThread extends Thread {

   @Override
   public void run() {
       System.out.println("I'm Thread! My name is " + getName());
   }
}
Барои эҷод ва оғоз кардани риштаҳо, мо бояд синф эҷод кунем ва онро аз java.lang. Threadва усулро дар он бекор кунед run(). Охирин хеле муҳим аст. Маҳз дар усуле, ки run()мо мантиқеро муқаррар мекунем, ки риштаи мо бояд иҷро шавад. Ҳоло, агар мо як мисол эҷод кунем MyFirstThreadва онро иҷро кунем, усул run()сатри номи худро ба консол чоп мекунад: усул getName()номи "система"-и риштаро чоп мекунад, ки ба таври худкор таъин карда мешавад. Ҳарчанд, дар асл, чаро "агар"? Биёед эҷод кунем ва озмоиш кунем!
public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {

           MyFirstThread thread = new MyFirstThread();
           thread.start();
       }
   }
}
Натиҷаи консол: Ман Thread ҳастам! Номи ман Thread-2 Ман Thread ҳастам! Номи ман Thread-1 Ман Thread ҳастам! Номи ман Thread-0 Ман Thread ҳастам! Номи ман Thread-3 Ман Thread ҳастам! Номи ман Thread-6 Ман Thread ҳастам! Номи ман Thread-7 Ман Thread ҳастам! Номи ман Thread-4 Ман Thread ҳастам! Номи ман Thread-5 Ман Thread ҳастам! Номи ман Thread-9 Ман Thread ҳастам! Номи ман Thread-8 Мо 10 ришта (an object) эҷод мекунем MyFirstThread, ки аз онҳо мерос мегиранд Threadва онҳоро тавассути даъват ба усули an object оғоз мекунанд start(). Пас аз даъват кардани метод , start()усули он ба кор оғоз мекунад run()ва мантиқи дар он навишташуда иҷро мешавад. Лутфан таваҷҷӯҳ намоед: номҳои риштаҳо мувофиқ нестанд. Хеле аҷиб аст, чаро онҳо бо навбат ба қатл расонида нашуданд: Thread-0, Thread-1, Thread-2ва ғайра? Ин маҳз як мисоли он аст, ки тафаккури стандартӣ ва "пайвандӣ" кор намекунад. Гап дар сари он аст, ки дар ин ҳолат мо танҳо фармон медиҳем, ки 10 ришта эҷод ва оғоз кунад. Бо кадом тартиб онҳо бояд ба кор андохта шаванд, нақшаи ришта муайян мекунад: механизми махсус дар дохor системаи оператсионӣ. Он чӣ гуна дақиқ сохта шудааст ва аз рӯи кадом принсип қарор қабул мекунад, як мавзӯи хеле мураккаб аст ва мо ҳоло ба он ғарқ намешавем. Чизи асосии дар хотир доштан дар он аст, ки барномасоз пайдарпайии иҷрои риштаро назорат карда наметавонад. Барои фаҳмидани ҷиддияти вазъият, кӯшиш кунед, ки усулро main()аз мисоли дар боло овардашуда якчанд маротиба иҷро кунед. Натиҷаи дуюми консол: Ман Thread ҳастам! Номи ман Thread-0 Ман Thread ҳастам! Номи ман Thread-4 Ман Thread ҳастам! Номи ман Thread-3 Ман Thread ҳастам! Номи ман Thread-2 Ман Thread ҳастам! Номи ман Thread-1 Ман Thread ҳастам! Номи ман Thread-5 Ман Thread ҳастам! Номи ман Thread-6 Ман Thread ҳастам! Номи ман Thread-8 Ман Thread ҳастам! Номи ман Thread-9 Ман Thread ҳастам! Номи ман Thread-7 Намоиши консоли сеюм: Ман Thread ҳастам! Номи ман Thread-0 Ман Thread ҳастам! Номи ман Thread-3 Ман Thread ҳастам! Номи ман Thread-1 Ман Thread ҳастам! Номи ман Thread-2 Ман Thread ҳастам! Номи ман Thread-6 Ман Thread ҳастам! Номи ман Thread-4 Ман Thread ҳастам! Номи ман Thread-9 Ман Thread ҳастам! Номи ман Thread-5 Ман Thread ҳастам! Номи ман Thread-7 Ман Thread ҳастам! Номи ман Thread-8 аст

Мушкилоте, ки чанд ришта эҷод мекунанд

Дар мисоли китобҳо шумо дидед, ки бисёрҷабҳаҳо масъалаҳои хеле муҳимро ҳал мекунанд ва истифодаи он кори барномаҳои моро метезонад. Дар бисёр мавридҳо - бисёр маротиба. Аммо бесабаб нест, ки чанд ришта мавзӯи мураккаб ҳисобида мешавад. Охир, агар нодуруст истифода бурда шавад, ба чои халли онхо проблемахо ба вучуд меоварад. Вақте ки ман мегӯям, ки "мушкилот эҷод кунед", ман чизи абстрактиро дар назар надорам. Ду мушкилоти мушаххасе вуҷуд доранд, ки чанд ришта метавонад ба вуҷуд ояд: басташавӣ ва ҳолати мусобиқа. Бунбаст вазъиятест, ки дар он риштаҳои сершумор мунтазири захираҳои аз ҷониби ҳамдигар ишғолшуда мебошанд ва ҳеҷ яке аз онҳо наметавонад иҷроро идома диҳад. Мо дар лексияҳои оянда дар ин бора бештар сӯҳбат хоҳем кард, аммо ҳоло ин мисол кофӣ хоҳад буд: Multithreading дар Java: моҳият, афзалиятҳо ва домҳои умумӣ - 4 Тасаввур кунед, ки ришта-1 бо баъзе Объект-1 кор мекунад ва ришта-2 бо Объект-2 кор мекунад. Барнома чунин навишта шудааст:
  1. Thread-1 кор бо Объект-1-ро қатъ мекунад ва ба Объект-2 мегузарад, вақте ки Thread-2 кор бо Объекти 2-ро қатъ мекунад ва ба Объект-1 мегузарад.
  2. Thread-2 кор бо Объект-2-ро қатъ мекунад ва ба Объект-1 мегузарад, вақте ки Thread-1 кор бо Объекти 1-ро қатъ мекунад ва ба Объект-2 мегузарад.
Ҳатто бе дониши амиқ дар бораи чанд ришта, шумо метавонед ба осонӣ дарк кунед, ки аз он ҳеҷ чиз ба даст намеояд. Риштаҳо ҳеҷ гоҳ ҷой иваз намекунанд ва то абад интизори ҳамдигар хоҳанд буд. Хатогӣ равшан ба назар мерасад, аммо дар асл чунин нест. Шумо метавонед онро ба осонӣ ба барнома иҷозат диҳед. Мо дар лексияҳои зерин мисолҳои codeеро дида мебароем, ки боиси бунбаст мегардад. Дар омади гап, Quora як мисоли воқеии воқеиро дорад, ки чӣ будани бунбастро мефаҳмонад . "Дар баъзе иёлатҳои Ҳиндустон, агар шумо ҳамчун фермер сабти ном нашуда бошед, онҳо ба шумо заминҳои кишоварзиро намефурӯшанд. Аммо, агар шумо замини кишоварзӣ надоред, ба қайд гирифта намешавед». Аҷоиб, ман чӣ гуфта метавонам! :) Акнун дар бораи шарти мусобика — вазъияти мусобика. Multithreading дар Java: моҳият, афзалиятҳо ва домҳои умумӣ - 5Ҳолати мусобиқа як камбудии тарҳрезӣ дар система ё замимаи бисёрсоҳавӣ мебошад, ки дар он кори система ё барнома аз тартиби иҷро шудани қисмҳои code вобаста аст. Мисоли бо риштаҳои иҷрошавандаро дар хотир доред:
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();
       }
   }
}
Акнун тасаввур кунед, ки барнома барои кори роботе, ки хӯрок тайёр мекунад, масъул аст! Ришта-0 тухмро аз яхдон мебарорад. Ҷараёни 1 оташдонро ба кор медарорад. «Стрим-2» табақчаро бароварда ба болои печка мегузорад. Маҷрои 3 дар болои печка оташ мегирад. Ҷараёни 4 ба табақ равған рехт. Ҷараёни 5 тухмҳоро мешиканад ва онҳоро ба табақи frying мерезад. Ҷараёни 6 снарядҳоро ба қуттии партов мепартояд. Stream-7 тухми пухтаи тайёрро аз гармӣ дур мекунад. «Поток-8» тухми пухтаро ба табак мегузорад. «Стрим-9» зарфхоро мешуяд. Ба натиҷаҳои барномаи мо нигаред: Thread-0 иҷро карда шуд Thread-2 иҷро карда шуд Thread-1 вентилятор иҷро карда шуд Thread-4 иҷро карда шуд Thread-9 executed Thread-5 сетои иҷрошуда Thread-8 иҷро карда шуд Thread-7 Thread-7 иҷро шуд. ришта иҷро шуд -3 Ришта-6 иҷро шуд Оё скрипт шавқовар аст? :) Ва ҳама аз он сабаб, ки кори барномаи мо аз тартиби иҷро шудани риштаҳо вобаста аст. Ҳангоми каме вайрон кардани пайдарпай, ошхонаи мо ба дӯзах табдил меёбад ва роботе, ки девона шудааст, ҳама чизро дар атрофи он нест мекунад. Ин инчунин як мушкor маъмул дар барномасозии бисёрсоҳавӣ аст, ки шумо дар бораи он на як бор мешунавед. Дар охири лексия ман мехостам ба шумо китоберо оид ба бисёрсоҳавӣ тавсия диҳам.
Multithreading дар Java: моҳият, афзалиятҳо ва домҳои умумӣ - 6
"Concurrency Java in Practice" дар соли 2006 навишта шуда буд, аммо аҳамияти худро гум накардааст. Он барномасозии бисёрсоҳаи Java-ро дар бар мегирад, ки аз асосҳо сар карда, бо рӯйхати хатогиҳои маъмултарин ва антипаттернҳо анҷом меёбад. Агар шумо ягон вақт тасмим гиред, ки як гуруи бисёрсоҳаи барномасозӣ шавед, ин китоб ҳатмист. Дар лексияҳои оянда вохӯрем! :)
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION