JavaRush /Java Blogu /Random-AZ /Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları. 3-c...
Roman Beekeeper
Səviyyə

Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları. 3-cü hissə

Qrupda dərc edilmişdir
Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları. Hissə 1 Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları. 2-ci hissə

Çox iş parçacığı

37. Java-da yeni mövzu (axın) necə yaradılır?

Bu və ya digər şəkildə yaradılma Thread sinfindən istifadə etməklə baş verir. Amma burada seçimlər ola bilər...
  1. -dən miras alırıqjava.lang.Thread
  2. java.lang.RunnableBiz obyekti konstruktor Threadsinfini qəbul edən interfeysi həyata keçiririk
Gəlin onların hər biri haqqında danışaq.

Biz Thread sinfindən miras alırıq

Bu işi yerinə yetirmək üçün sinifimizdə miras alırıq java.lang.Thread. Tərkibində meth var run(), bu da bizə lazım olan şeydir. Yeni ipin bütün həyatı və məntiqi bu üsulda olacaq. mainBu , yeni mövzu üçün bir növ üsuldur . Bundan sonra, sinifimizin bir obyektini yaratmaq və start()yeni bir mövzu yaradacaq və orada yazılmış məntiqi işlədəcək metodu yerinə yetirmək qalır. Baxaq:
/**
* Пример того, How создавать треды путем наследования {@link Thread} класса.
*/
class ThreadInheritance extends Thread {

   @Override
   public void run() {
       System.out.println(Thread.currentThread().getName());
   }

   public static void main(String[] args) {
       ThreadInheritance threadInheritance1 = new ThreadInheritance();
       ThreadInheritance threadInheritance2 = new ThreadInheritance();
       ThreadInheritance threadInheritance3 = new ThreadInheritance();
       threadInheritance1.start();
       threadInheritance2.start();
       threadInheritance3.start();
   }
}
Konsol çıxışı belə olacaq:

Thread-1
Thread-0
Thread-2
Yəni, burada da görürük ki, iplər növbə ilə deyil, JVM-nin qərar verdiyi kimi icra olunur)

Runnable interfeysinin həyata keçirilməsi

Əgər siz mirasın əleyhinəsinizsə və/və ya artıq digər siniflərdən birini miras alırsınızsa, java.lang.Runnable. Budur, sinifimizdə biz bu interfeysi həyata keçiririk və run()həmin nümunədə olduğu kimi metodu həyata keçiririk. Sadəcə daha çox obyekt yaratmalısınız Thread. Daha çox xətlərin daha pis olduğu görünür. Amma biz mirasın nə qədər zərərli olduğunu bilirik və bundan hər vasitə ilə qaçmaq daha yaxşıdır ;) Baxaq:
/**
* Пример того, How создавать треды из интерфейса {@link Runnable}.
* Здесь проще простого - реализуем этот интерфейс и потом передаем в конструктор
* экземпляр реализуемого an object.
*/
class ThreadInheritance implements Runnable {

   @Override
   public void run() {
       System.out.println(Thread.currentThread().getName());
   }

   public static void main(String[] args) {
       ThreadInheritance runnable1 = new ThreadInheritance();
       ThreadInheritance runnable2 = new ThreadInheritance();
       ThreadInheritance runnable3 = new ThreadInheritance();

       Thread threadRunnable1 = new Thread(runnable1);
       Thread threadRunnable2 = new Thread(runnable2);
       Thread threadRunnable3 = new Thread(runnable3);

       threadRunnable1.start();
       threadRunnable2.start();
       threadRunnable3.start();
   }
}
Və icra nəticəsi:

Thread-0
Thread-1
Thread-2

38. Proseslə iplik arasındakı fərq nədir?

Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları.  Hissə 3 - 1Proses və iplik arasında aşağıdakı fərqlər var:
  1. İcra olunan proqram proses adlanır, Thread isə prosesin alt çoxluğudur.
  2. Proseslər müstəqildir, iplər isə prosesin alt hissəsidir.
  3. Proseslərin yaddaşda fərqli ünvan sahəsi var, mövzular isə ümumi ünvan sahəsini ehtiva edir.
  4. Kontekstlərin dəyişdirilməsi proseslərlə müqayisədə mövzular arasında daha sürətli olur.
  5. Proseslərarası əlaqə, mövzulararası əlaqədən daha yavaş və daha bahalıdır.
  6. Ana prosesdəki hər hansı dəyişiklik uşaq prosesinə təsir göstərmir, halbuki ana ipdəki dəyişikliklər uşaq mövzuya təsir göstərə bilər.

39. Çoxmilliliyin üstünlükləri hansılardır?

Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları.  3-2 hissə
  1. Multithreading proqrama/proqramın bəzi fon tapşırıqlarını yerinə yetirməsinə baxmayaraq, həmişə daxil olanlara cavab verməyə imkan verir;
  2. Multithreading sizə tapşırıqları daha tez yerinə yetirməyə imkan verir, çünki iplər müstəqil şəkildə yerinə yetirilir;
  3. Multithreading daha yaxşı keş istifadəsini təmin edir, çünki mövzular ümumi yaddaş resurslarını paylaşır;
  4. Multithreading tələb olunan server miqdarını azaldır, çünki bir server eyni vaxtda bir neçə mövzu işlədə bilər.

40. Sapın həyat tsiklində hansı vəziyyətlər var?

Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları.  3-3-cü hissə
  1. Yeni: Bu vəziyyətdə, Threadyeni operatordan istifadə edərək sinif obyekti yaradılır, lakin mövzu mövcud deyil. Biz zəng edənə qədər mövzu başlamır start().
  2. Runnable: Bu vəziyyətdə, mövzu metodu çağırdıqdan sonra işləməyə hazırdır başlamaq(). Bununla belə, mövzu planlayıcısı tərəfindən hələ seçilməyib.
  3. Çalışır: Bu vəziyyətdə, iplik planlaşdırıcı hazır vəziyyətdən bir ip seçir və işləyir.
  4. Gözləyir/Bloklanır: Bu vəziyyətdə mövzu işləmir, lakin hələ də canlıdır və ya başqa bir başlığın tamamlanmasını gözləyir.
  5. Ölü/Xitam: Metod çıxdıqda, run()ip dayandırılmış və ya ölü vəziyyətdədir.

41. Mövzu iki dəfə başlamaq olarmı?

Xeyr, biz ipi yenidən başlada bilmərik, çünki ip işə salındıqdan və icra edildikdən sonra o, Ölü vəziyyətə keçir. Beləliklə, biz mövzunu iki dəfə işə salmağa çalışsaq, o, runtimeException " java.lang.IllegalThreadStateException " atacaq . Baxaq:
class DoubleStartThreadExample extends Thread {

   /**
    * Имитируем работу треда
    */
   public void run() {
	// что-то происходит. Для нас не существенно на этом этапе
   }

   /**
    * Запускаем тред дважды
    */
   public static void main(String[] args) {
       DoubleStartThreadExample doubleStartThreadExample = new DoubleStartThreadExample();
       doubleStartThreadExample.start();
       doubleStartThreadExample.start();
   }
}
İş eyni mövzunun ikinci başlanğıcına çatan kimi, istisna olacaq. Özünüz cəhd edin;) yüz dəfə eşitməkdənsə, bir dəfə görmək yaxşıdır.

42. Əgər start() metodunu çağırmadan birbaşa run() metodunu çağırsanız necə?

Bəli, run()əlbəttə ki, bir metod çağıra bilərsiniz, lakin bu, yeni bir başlıq yaratmayacaq və onu ayrıca bir ip kimi icra etməyəcək. Bu halda, sadə metodu çağıran sadə bir obyektdir. Söhbət üsuldan gedirsə start(), bu, başqa məsələdir. Bu metodu işə salmaqla runtimeyenisini işə salır və o da öz növbəsində bizim metodumuzu işə salır;) Mənə inanmırsınızsa, cəhd edin:
class ThreadCallRunExample extends Thread {

   public void run() {
       for (int i = 0; i < 5; i++) {
           System.out.print(i);
       }
   }

   public static void main(String args[]) {
       ThreadCallRunExample runExample1 = new ThreadCallRunExample();
       ThreadCallRunExample runExample2 = new ThreadCallRunExample();

       // просто будут вызваны в потоке main два метода, один за другим.
       runExample1.run();
       runExample2.run();
   }
}
Və konsolun çıxışı belə olacaq:

0123401234
Görünür ki, heç bir ip yaradılmayıb. Hər şey adi bir sinif kimi işləyirdi. Əvvəlcə birinci sinif metodu işlədi, sonra ikinci.

43. Demon ipi nədir?

Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları.  3-4-cü hissəDaemon ipi (bundan sonra daemon ipi adlandırılacaq) başqa bir iplə əlaqəli olaraq arxa planda tapşırıqları yerinə yetirən ipdir. Yəni onun işi yalnız başqa (əsas) iplə birlikdə yerinə yetirilməsi lazım olan köməkçi işləri yerinə yetirməkdir. Avtomatik işləyən bir çox demon ipləri var, məsələn, Çöp Kollektoru, yekunlaşdırıcı və s.

Java niyə demon ipini bağlayır?

Daemon mövzusunun yeganə məqsədi odur ki, arxa plana dəstək tapşırığı üçün istifadəçi ipinə xidmətlər təqdim edir. Buna görə də, əgər əsas mövzu tamamlanıbsa, iş vaxtı avtomatik olaraq onun bütün demon iplərini bağlayır.

Thread sinfində işləmə üsulları

Sinif java.lang.Threadiplik demonu ilə işləmək üçün iki üsul təqdim edir:
  1. public void setDaemon(boolean status)- bunun bir demon ipi olacağını göstərir. Varsayılan olaraq false, ayrı-ayrılıqda göstərilmədikcə qeyri-daemon mövzuları yaradılacaq.
  2. public boolean isDaemon()daemon- mahiyyətcə bu, əvvəlki metoddan istifadə edərək təyin etdiyimiz dəyişən üçün alıcıdır .
Misal:
class DaemonThreadExample extends Thread {

   public void run() {
       // Проверяет, демон ли этот поток or нет
       if (Thread.currentThread().isDaemon()) {
           System.out.println("daemon thread");
       } else {
           System.out.println("user thread");
       }
   }

   public static void main(String[] args) {
       DaemonThreadExample thread1 = new DaemonThreadExample();
       DaemonThreadExample thread2 = new DaemonThreadExample();
       DaemonThreadExample thread3 = new DaemonThreadExample();

       // теперь thread1 - поток-демон.
       thread1.setDaemon(true);

       System.out.println("демон?.. " + thread1.isDaemon());
       System.out.println("демон?.. " + thread2.isDaemon());
       System.out.println("демон?.. " + thread3.isDaemon());

       thread1.start();
       thread2.start();
       thread3.start();
   }
}
Konsol çıxışı:

демон?.. true
демон?.. false
демон?.. false
daemon thread
user thread
user thread
Çıxışdan görürük ki, ipin özünün içərisində statik currentThread()üsuldan istifadə edərək, bir tərəfdən onun hansı iplik olduğunu öyrənə bilərik, digər tərəfdən bu ipin obyektinə istinadımız varsa, öyrənə bilərik. birbaşa ondan. Bu, konfiqurasiyada lazımi çevikliyi verir.

44. İp yaradıldıqdan sonra onu demon etmək olarmı?

Yox. Bunu etsəniz, bir istisna atacaq IllegalThreadStateException. Buna görə də, başlamazdan əvvəl yalnız bir demon ipi yarada bilərik. Misal:
class SetDaemonAfterStartExample extends Thread {

   public void run() {
       System.out.println("Working...");
   }

   public static void main(String[] args) {
       SetDaemonAfterStartExample afterStartExample = new SetDaemonAfterStartExample();
       afterStartExample.start();

       // здесь будет выброшено исключение
       afterStartExample.setDaemon(true);
   }
}
Konsol çıxışı:

Working...
Exception in thread "main" java.lang.IllegalThreadStateException
	at java.lang.Thread.setDaemon(Thread.java:1359)
	at SetDaemonAfterStartExample.main(SetDaemonAfterStartExample.java:14)

45. Kapatma qancası nədir?

Shutdownhook , JVM (Java Virtual Maşın) bağlanmazdan əvvəl gizli olaraq çağırılan bir mövzudur. Beləliklə, Java Virtual Maşın normal və ya qəfil sönəndə resursu təmizləmək və ya vəziyyəti saxlamaq üçün ondan istifadə edə bilərik. shutdown hookAşağıdakı üsuldan istifadə edərək əlavə edə bilərik :
Runtime.getRuntime().addShutdownHook(new ShutdownHookThreadExample());
Nümunədə göstərildiyi kimi:
/**
* Программа, которая показывает How запустить shutdown hook тред,
* который выполнится аккурат до окончания работы JVM
*/
class ShutdownHookThreadExample extends Thread {

   public void run() {
       System.out.println("shutdown hook задачу выполнил");
   }

   public static void main(String[] args) {

       Runtime.getRuntime().addShutdownHook(new ShutdownHookThreadExample());

       System.out.println("Теперь программа засыпает, нажмите ctrl+c чтоб завершить ее.");
       try {
           Thread.sleep(60000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
   }
}
Konsol çıxışı:

Теперь программа засыпает, нажмите ctrl+c чтоб завершить ее.
shutdown hook задачу выполнил

46. ​​Sinxronizasiya nədir?

Java-da sinxronizasiya çoxlu mövzuların istənilən paylaşılan mənbəyə çıxışını idarə etmək qabiliyyətidir. Birdən çox mövzu eyni tapşırığı yerinə yetirməyə çalışdıqda, səhv nəticə ehtimalı var, buna görə də bu problemi aradan qaldırmaq üçün Java sinxronizasiyadan istifadə edir, buna görə eyni anda yalnız bir ip işləyə bilər. Sinxronizasiya üç yolla əldə edilə bilər:
  • Sinxronizasiya üsulu
  • Müəyyən bir bloku sinxronizasiya etməklə
  • Statik sinxronizasiya

Metodun sinxronizasiyası

Sinxronlaşdırılmış üsul hər hansı paylaşılan resurs üçün obyekti kilidləmək üçün istifadə olunur. İp sinxronlaşdırılmış metodu çağırdıqda, o, avtomatik olaraq həmin obyektdə kilid əldə edir və ip öz vəzifəsini tamamladıqdan sonra onu buraxır. Bunun işləməsi üçün sinxronlaşdırılmış açar söz əlavə etməlisiniz . Bunun bir nümunə ilə necə işlədiyini görək:
/**
* Пример, где мы синхронизируем метод. То есть добавляем ему слово synchronized.
* Есть два писателя, которые хотят использовать один принтер. Они подготовor свои поэмы
* И конечно же не хотят, чтоб их поэмы перемешались, а хотят, чтоб работа была сделана по * * * очереди для каждого из них
*/
class Printer {

   synchronized void print(List<String> wordsToPrint) {
       wordsToPrint.forEach(System.out::print);
       System.out.println();
   }

   public static void main(String args[]) {
       // один an object для двух тредов
       Printer printer  = new Printer();

       // создаем два треда
       Writer1 writer1 = new Writer1(printer);
       Writer2 writer2 = new Writer2(printer);

       // запускаем их
       writer1.start();
       writer2.start();
   }
}

/**
* Писатель номер 1, который пишет свою поэму.
*/
class Writer1 extends Thread {
   Printer printer;

   Writer1(Printer printer) {
       this.printer = printer;
   }

   public void run() {
       List<string> poem = Arrays.asList("Я ", this.getName(), " Пишу", " Письмо");
       printer.print(poem);
   }

}

/**
* Писатель номер 2, который пишет свою поэму.
*/
class Writer2 extends Thread {
   Printer printer;

   Writer2(Printer printer) {
       this.printer = printer;
   }

   public void run() {
       List<String> poem = Arrays.asList("Не Я ", this.getName(), " Не пишу", " Не Письмо");
       printer.print(poem);
   }
}
Və konsola çıxış:

Я Thread-0 Пишу Письмо
Не Я Thread-1 Не пишу Не Письмо

Sinxronizasiya bloku

Sinxronlaşdırılmış blok istənilən xüsusi metod resursunda sinxronizasiya etmək üçün istifadə edilə bilər. Deyək ki, böyük bir üsulda (bəli, bəli, belə şeylər yaza bilməzsən, amma bəzən olur) nədənsə yalnız kiçik bir hissəni sinxronlaşdırmaq lazımdır. Metodun bütün kodlarını sinxronlaşdırılmış bloka qoysanız, o, sinxronlaşdırılmış metodla eyni şəkildə işləyəcək. Sintaksis belə görünür:
synchronized (“an object для блокировки”) {
   // сам code, который нужно защитить
}
Əvvəlki nümunəni təkrarlamamaq üçün anonim siniflər vasitəsilə iplər yaradacağıq - yəni dərhal Runnable interfeysini həyata keçirəcəyik.
/**
* Вот How добавляется блок синхронизации.
* Внутри нужно указать у кого будет взят мьютекс для блокировки.
*/
class Printer {

   void print(List<String> wordsToPrint) {
       synchronized (this) {
           wordsToPrint.forEach(System.out::print);
       }
       System.out.println();
   }

   public static void main(String args[]) {
       // один an object для двух тредов
       Printer printer = new Printer();

       // создаем два треда
       Thread writer1 = new Thread(new Runnable() {
           @Override
           public void run() {
               List<String> poem = Arrays.asList("Я ", "Writer1", " Пишу", " Письмо");
               printer.print(poem);
           }
       });
       Thread writer2 = new Thread(new Runnable() {
           @Override
           public void run() {
               List<String> poem = Arrays.asList("Не Я ", "Writer2", " Не пишу", " Не Письмо");
               printer.print(poem);
           }
       });

       // запускаем их
       writer1.start();
       writer2.start();
   }
}

}
və konsola çıxış

Я Writer1 Пишу Письмо
Не Я Writer2 Не пишу Не Письмо

Statik sinxronizasiya

Statik metodu sinxronizasiya etsəniz, kilid obyektdə deyil, sinifdə olacaq. Bu nümunədə biz statik sinxronizasiyanı yerinə yetirmək üçün sinxronlaşdırılmış açar sözünü statik metoda tətbiq edirik:
/**
* Вот How добавляется блок синхронизации.
* Внутри нужно указать у кого будет взят мьютекс для блокировки.
*/
class Printer {

   static synchronized void print(List<String> wordsToPrint) {
       wordsToPrint.forEach(System.out::print);
       System.out.println();
   }

   public static void main(String args[]) {

       // создаем два треда
       Thread writer1 = new Thread(new Runnable() {
           @Override
           public void run() {
               List<String> poem = Arrays.asList("Я ", "Writer1", " Пишу", " Письмо");
               Printer.print(poem);
           }
       });
       Thread writer2 = new Thread(new Runnable() {
           @Override
           public void run() {
               List<String> poem = Arrays.asList("Не Я ", "Writer2", " Не пишу", " Не Письмо");
               Printer.print(poem);
           }
       });

       // запускаем их
       writer1.start();
       writer2.start();
   }
}
və konsola çıxış:

Не Я Writer2 Не пишу Не Письмо
Я Writer1 Пишу Письмо

47. Dəyişən dəyişən nədir?

Açar söz volatileçox yivli proqramlaşdırmada mövzu təhlükəsizliyini təmin etmək üçün istifadə olunur, çünki bir dəyişən dəyişənə modifikasiya bütün digər mövzulara görünür, beləliklə, bir dəyişən eyni anda bir ip tərəfindən istifadə edilə bilər. Açar sözdən istifadə edərək, volatiledəyişənin mövzu üçün təhlükəsiz olacağına və paylaşılan yaddaşda saxlanacağına və mövzuların onu öz keşinə götürməyəcəyinə zəmanət verə bilərsiniz. Nə kimi görünür?
private volatile AtomicInteger count;
Biz sadəcə dəyişənə əlavə edirik volatile. Amma bu, tam iplik təhlükəsizliyi demək deyil... Axı əməliyyatlar dəyişən üzərində atomik olmaya bilər. AtomicAncaq əməliyyatı atomik şəkildə yerinə yetirən siniflərdən, yəni prosessor tərəfindən bir icrada istifadə edə bilərsiniz . Bir çox belə sinifləri paketdə tapmaq olar java.util.concurrent.atomic.

48. Çıxış nədir

Java-da çıxılmaz vəziyyət multithreading hissəsidir. Bir ipin başqa bir ip tərəfindən əldə edilmiş bir obyekt kilidini gözlədiyi və ikinci ipin birinci ip tərəfindən əldə edilmiş bir obyekt kilidini gözlədiyi bir vəziyyətdə kilidlənmə baş verə bilər. Beləliklə, bu iki mövzu bir-birini gözləyir və kodlarının icrasına davam etməyəcək. Ən yaxşı 50 Java Əsas Müsahibə Sualları və Cavabları.  3-5-ci hissəRunnable tətbiqini həyata keçirən bir sinifin olduğu bir nümunəyə baxaq. Konstruktorda iki resursu qəbul edir. Run() metodunun içərisində o, onlar üçün kilidi bir-bir götürür, beləliklə, bu sinifin iki obyektini yaradıb resursları müxtəlif sifarişlərdə köçürsəniz, asanlıqla kilidlə qarşılaşa bilərsiniz:
class DeadLock {

   public static void main(String[] args) {
       final Integer r1 = 10;
       final Integer r2 = 15;

       DeadlockThread threadR1R2 = new DeadlockThread(r1, r2);
       DeadlockThread threadR2R1 = new DeadlockThread(r2, r1);

       new Thread(threadR1R2).start();
       new Thread(threadR2R1).start();
   }
}

/**
* Класс, который принимает два ресурса.
*/
class DeadlockThread implements Runnable {

   private final Integer r1;
   private final Integer r2;

   public DeadlockThread(Integer r1, Integer r2) {
       this.r1 = r1;
       this.r2 = r2;
   }

   @Override
   public void run() {
       synchronized (r1) {
           System.out.println(Thread.currentThread().getName() + " захватил ресурс: " + r1);

           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }

           synchronized (r2) {
               System.out.println(Thread.currentThread().getName() + " захватил ресурс: " + r2);
           }
       }
   }
}
Konsol çıxışı:

Первый тред захватил первый ресурс
Второй тред захватывает второй ресурс

49. Dalandan necə qaçmaq olar?

Bir dalana dirənmənin necə baş verdiyini bildiklərimizə əsaslanaraq bəzi nəticələr çıxara bilərik...
  • Yuxarıdakı nümunədə göstərildiyi kimi, çıxılmaz vəziyyət kilidlərin yuvalanması ilə əlaqədar idi. Yəni bir qıfılın içərisində digəri və ya daha çoxu var. Bunun qarşısını aşağıdakı şəkildə ala bilərsiniz - yuva qurmaq əvəzinə, üstünə yeni bir abstraksiya əlavə etmək və kilidi daha yüksək səviyyəyə vermək və yuvalanmış kilidləri çıxarmaq lazımdır.
  • Bloklama nə qədər çox olarsa, dalana dirənmə ehtimalı bir o qədər çox olar. Buna görə də, hər dəfə bir kilid əlavə etdikdə, bunun həqiqətən lazım olub-olmadığını və yenisini əlavə etməyin qarşısını almaq mümkün olub olmadığını düşünməlisiniz.
  • İstifadə edir Thread.join(). Bir başlıq digərini gözlədiyi zaman da çıxılmaz vəziyyət yarana bilər. join()Bu problemin qarşısını almaq üçün metoda vaxt məhdudiyyəti qoymağı düşünə bilərsiniz .
  • Bir mövzumuz olsa, heç bir dalana düçar olmaz;)

50. Yarış şərti nədir?

Həqiqi yarışlarda avtomobillər çıxış edirsə, o zaman çox yivliliyin yarış terminologiyasında iplər yarışlarda çıxış edir. Bəs niyə? Çalışan və eyni obyektə çıxışı olan iki mövzu var. Və eyni zamanda vəziyyəti yeniləməyə cəhd edə bilərlər. İndiyə qədər hər şey aydındır, elə deyilmi? Beləliklə, iplər ya real paralel (əgər prosessorda birdən çox nüvə varsa) və ya prosessor qısa müddət ayırdıqda şərti olaraq paralel işləyir. Və biz bu proseslərə nəzarət edə bilmirik, ona görə də təminat verə bilmərik ki, bir mövzu obyektdən verilənləri oxuduqda, başqa bir iplik bunu etməzdən ƏVVƏL onu dəyişməyə vaxtı olacaq. Bu sınaq və hərəkət birləşməsindən keçdikdə belə problemlər baş verir. Bunun mənası nədi? Məsələn, ifbədənində şərtin özünün dəyişdiyi bir ifadə var, yəni:
int z = 0;

// проверь
if (z < 5) {
//действуй
   z = z + 5;
}
Beləliklə, elə bir vəziyyət yarana bilər ki, z hələ də sıfıra bərabər olan və birlikdə bu dəyəri dəyişdiyi bir vaxtda bu kod blokuna iki mövzu eyni vaxtda daxil olur. Və sonda gözlənilən 5 deyil, 10 dəyərini almayacağıq. Bunun qarşısını necə almaq olar? İcradan əvvəl və sonra kilidləmək lazımdır. Yəni, bloka daxil olan ilk ip üçün ifbütün hərəkətləri yerinə yetirin, dəyişdirin zvə yalnız bundan sonra növbəti ipə bunu etmək imkanı verin. Lakin növbəti mövzu bloka daxil olmayacaq if, çünki zo, artıq 5-ə bərabər olacaq:
// получить блокировку для z
if (z < 5) {
   z = z + 5;
}
// выпустить из блокировки z
===================================================

Çıxış əvəzinə

Sona qədər oxuyan hər kəsə təşəkkür etmək istəyirəm. Bu uzun bir səyahət idi və siz bunu bacardınız! Hər şey aydın olmaya bilər. Bu yaxşıdır. Java dilini öyrənməyə başlayan kimi statik dəyişənin nə olduğunu başa düşə bilmədim. Amma heç nə, bu fikirlə yatdım, daha bir neçə mənbə oxudum və nəhayət başa düşdüm. Müsahibəyə hazırlaşmaq praktiki işdən daha çox akademik məsələdir. Buna görə də, hər müsahibədən əvvəl çox tez-tez istifadə etmədiyiniz şeyləri təkrarlamalı və yaddaşınızı təzələməlisiniz.

Həmişə olduğu kimi, faydalı bağlantılar:

Oxuduğunuz üçün hamınıza təşəkkür edirəm, tezliklə görüşərik) GitHub-dakı profilim
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION