1. İcra axını (thread) nədir
Axın müstəqil iş xətti kimi
Java-da (və ümumiyyətlə proqramlaşdırmada) icra axını — bu, bir proqram daxilində digər axınlarla paralel işləyən müstəqil əmrlər ardıcıllığıdır. Fabrikanı təsəvvür edin: hər dərzinin öz iş masası və tapşırığı var, o müstəqil işləyir, amma hamısı birlikdə ümumi nəticəyə xidmət edir.
Standart olaraq Java-proqram bir axınla başlayır — metod main-i işə salan axın. Amma proqramın müxtəlif hissələrinin eyni vaxtda yerinə yetirilməsi üçün əlavə axınlar yarada bilərik.
Proseslər və axınlar: fərq nədir?
- Proses — «ağır» icra vahididir. Hər bir prosesin öz yaddaş sahəsi, öz dəyişənləri, öz resursları var. Proseslər bir-birindən tam təcrid olunub — biri «şəkkə düşsə», başqaları zərər görməz.
- Axın (thread) — proses daxilində «yüngül» icra vahididir. Eyni prosesin bütün axınları yaddaşı və resursları bölüşür. Bu o deməkdir ki, onlar asanlıqla məlumat mübadiləsi edə bilirlər (və, təəssüf ki, bir-birinə asanlıqla mane də ola bilirlər).
Bənzətmə:
Proses — ayrıca mənzil: hərəsinin öz divarları və sakinləri var.
Axınlar — eyni mənzilin sakinləri: hərəsinin öz işi var, amma mətbəx və vanna ortaqdır.
Bu Java-da necə görünür?
Proqramı işə saldığınızda, JVM ən azı bir axın yaradır — əsas (main). Ancaq siz tapşırıqları paralel yerinə yetirmək üçün yeni axınlar yarada bilərsiniz.
2. Multithreading nə üçün lazımdır
Reaktivlik: UI «donmamalıdır»
Tutaq ki, siz qrafik proqram yazırsınız — məsələn, mətn redaktoru. İstifadəçi «Yadda saxla» düyməsini basdı, siz isə faylı diskə uzun-uzadı yazmağa başladınız. Bunu əsas axında etsəniz, proqram pəncərəsi «donacaq»: istifadəçi heç nəyi basa bilməyəcək, kursor tərpənməyəcək, interfeys reaksiya verməyəcək. Əgər faylı ayrıca axında saxlasanız — interfeys cavabdeh qalacaq və istifadəçi hətta fikrini dəyişib proqramı bağlaya da biləcək.
Həyati nümunə:
Siz brauzeri açıb böyük fayl yükləməyə başladınız. Əgər brauzer axınlardan istifadə etməsəydi, fayl yüklənənə qədər nə yeni vərəq aça, nə də səhifəni sürüşdürə bilərdiniz!
Məlumatların paralel emalı
Tutaq ki, emal olunmalı min fayldan ibarət siyahınız var (məsələn, heşləri yenidən hesablamaq və ya mətni əvəzləmək). Niyə onları paralel emal etməyək? Hər axın öz faylını götürüb müstəqil işləyir və bütün iş bir neçə dəfə tez başa çatır.
Nümunə:
Server yüzlərlə müştərinin sorğularını emal edir. Server bunu bir axında etsəydi, digər müştərilər növbələrini sonsuz gözləyərdilər. Axınlarla isə hər sorğu müstəqil emal olunur!
Çoxnüvəli prosessorlardan istifadə
Müasir prosessorlar — tək «beyin» deyil, paralel işləyə bilən bir komanda (nüvələr)dir. Əgər proqramınız yalnız bir axından istifadə edirsə, digər nüvələr darıxır və Minesweeper oynayır. Bir neçə axın işə salsanız — bütün nüvələr məşğul olur və proqram daha sürətli yerinə yetirilir.
Maraqlı fakt:
Telefonunuzun belə bir neçə nüvəsi var, noutbuk və serverlərdə isə — onlarla! Onların hamısından istifadə etməmək — avtobus almaq və onunla təkbaşına getmək kimidir.
3. Həyatdan nümunələr
| Sahə | Multithreading nümunəsi |
|---|---|
| Faylların yüklənməsi | Bir neçə faylın eyni vaxtda yüklənməsi |
| İstifadəçi interfeysi (UI) | Məlumatları yükləyərkən/saxlayarkən tətbiq «donmur» |
| Serverlər | Çoxsaylı şəbəkə sorğularının paralel emalı |
| Oyunlar | Fizika, qrafika, musiqi, AI üçün ayrı axınlar |
| Mesencerlər | Mesajların qəbulu, fayl göndərmə, interfeysin yenilənməsi |
| Video emalı | Kadrların paralel emalı |
Mini-bənzətmə:
Aşpaz şorba bişirir, paralel olaraq soba piroq bişirir, robot-tozsoran isə döşəməni təmizləyir — bunların hamısı eyni vaxtda baş verir və nahar daha tez hazır olur!
4. Multithreading-in potensial çətinlikləri
Race condition (yarış vəziyyəti)
Bir neçə axın eyni dəyişəni eyni anda dəyişəndə, nəticə proqnozlaşdırılmaya bilər. Məsələn, iki axın ümumi sayğacı eyni vaxtda artırsa, yekun dəyər səhv ola bilər. Bunun haqqında növbəti mühazirələrdən birində daha ətraflı danışacağıq.
Sinxronizasiya
Axınların bir-birinə mane olmaması üçün «razılaşma» yolları tapmaq lazımdır — kim nə zaman məlumatları dəyişə bilər. Buna sinxronizasiya deyilir. Bunun üçün xüsusi açar sözlər və konstruksiyalar var (synchronized, bloklamalar və s.), onlar haqqında sonra danışacağıq.
Deadlock (qarşılıqlı bloklanma)
Bəzən axınlar elə «dostlaşır» ki, bir-birini sonsuz gözləyirlər və proqram donur. Buna deadlock deyilir — və bu, çoxaxınlı proqramlaşdırmada ən məkrli xətalardan biridir.
Sazlama və testləmə
Çoxaxınlı proqramlardakı xətələri tutmaq çox çətindir: bəzən hər şey işləyir, bəzən — yox. Bəzən xəta yalnız serverdə və ya istifadəçidə üzə çıxır, sizdə isə hər şey ideal olur. Bu isə çoxaxınlı kodun testini və sazlanmasını proqramçı üçün əsl kvestə çevirir.
5. Qısa icmal: multithreading-li proqram necə görünür
Axınsız nümunə:
public class Main {
public static void main(String[] args) {
// 5-ə qədər sayırıq
for (int i = 1; i <= 5; i++) {
System.out.println(i);
}
// Hərfləri çap edirik
for (char c = 'A'; c <= 'E'; c++) {
System.out.println(c);
}
}
}
Çıxış həmişə eynidir:
1
2
3
4
5
A
B
C
D
E
Axınlı nümunə:
public class Main {
public static void main(String[] args) {
Thread numbers = new Thread(() -> {
for (int i = 1; i <= 5; i++) {
System.out.println(i);
try {
Thread.sleep(100); // Bir az gözləyək
} catch (InterruptedException e) {
// Gözardı edirik
}
}
});
Thread letters = new Thread(() -> {
for (char c = 'A'; c <= 'E'; c++) {
System.out.println(c);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// Gözardı edirik
}
}
});
numbers.start();
letters.start();
}
}
Çıxış qarışıq olacaq:
1
A
2
B
3
C
4
D
5
E
və ya, əgər axınlar «yarışırsa», ardıcıllıq başqa cür də ola bilər. Əsas odur — hər iki dövr paralel gedir!
6. Faydalı nüanslar
Vizual sxem: axınlar birlikdə necə işləyir
+-------------------+ +-------------------+
| Əsas axın | | İkinci axın |
+-------------------+ +-------------------+
| 1 | 2 | 3 | 4 | 5 | | A | B | C | D | E |
+-------------------+ +-------------------+
| |
| Hər ikisi |
| eyni vaxtda |
+-------------------------+
Java-da axınlar «pərdə arxasında» harada istifadə olunur
- Zibili toplama (Garbage Collector) — ayrı bir axın istifadə olunmayan obyektləri təmizləyir.
- Giriş-çıxış axınları (IO) — faylların oxunması və yazılması, şəbəkə bağlantıları.
- Serverlər və veb-tətbiqlər — hər bir müştəri sorğusu ayrıca axında emal olunur.
- Taymerlər, tapşırıq planlaşdırıcıları — tapşırıqların cədvələ görə icrası.
7. Yeni başlayanların tipik səhvləri
Səhv № 1: Axınların proqramı həmişə sürətləndirəcəyini gözləmək.
Əslində, əgər sizdə tək prosessorlu maşın varsa və ya işi düzgün təşkil etməmisinizsə, çoxaxınlılıq «qarışıqlıq» və axınlar arasında keçid üçün əlavə xərclər səbəbindən icranı hətta ləngidə bilər.
Səhv № 2: Sinxronizasiya problemlərini görməzdən gəlmək.
Çoxları əmindir: «Mən sadəcə iki axın işə salıram, nə pis gedə bilər ki?» Amma əgər hər iki axın eyni dəyişəni dəyişirsə, nəticə tamamilə gözlənilməz ola bilər.
Səhv № 3: Hər şey üçün axınlardan istifadə etmək.
Hər xırda şey üçün ayrıca axın işə salmağa dəyməz. Axınlar — resursdur və onların həddindən artıq çoxluğu ləngimələrə, hətta proqramın çökməsinə gətirib çıxara bilər.
Səhv № 4: Xətaların emal edilməməsi.
Axınlar istisnalar ata bilər (məsələn, fayllarla və ya şəbəkə ilə işləyərkən). Bu xətaları emal etməsəniz, proqram qəfil bağlana və ya «dona» bilər.
GO TO FULL VERSION