JavaRush /Blog Java /Random-MS /50 Soalan dan Jawapan Temuduga Teras Java Teratas. Bahagi...

50 Soalan dan Jawapan Temuduga Teras Java Teratas. Bahagian 3

Diterbitkan dalam kumpulan
50 Soalan dan Jawapan Temuduga Teras Java Teratas. Bahagian 1 Soalan dan Jawapan Temuduga Teras Java 50 Teratas. Bahagian 2

Multithreading

37. Bagaimana untuk mencipta benang baru (aliran) di Jawa?

Satu cara atau yang lain, penciptaan berlaku melalui penggunaan kelas Thread. Tetapi mungkin ada pilihan di sini...
  1. Kami mewarisi daripadajava.lang.Thread
  2. Kami melaksanakan antara muka yang objeknya menerima kelas java.lang.RunnablepembinaThread
Mari kita bercakap tentang setiap daripada mereka.

Kami mewarisi dari kelas Thread

Untuk membuat kerja ini, dalam kelas kami, kami mewarisi daripada java.lang.Thread. Ia mengandungi meth run(), iaitu apa yang kita perlukan. Semua kehidupan dan logik benang baru akan berada dalam kaedah ini. Ini adalah sejenis mainkaedah untuk benang baru. Selepas ini, semua yang tinggal adalah untuk mencipta objek kelas kami dan melaksanakan kaedah start(), yang akan mencipta benang baharu dan menjalankan logik yang ditulis di dalamnya. Mari lihat:
/**
* Пример того, 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();
   }
}
Output ke konsol akan menjadi seperti ini:

Thread-1
Thread-0
Thread-2
Iaitu, walaupun di sini kita melihat bahawa utas dilaksanakan bukan mengikut giliran, tetapi seperti yang diputuskan oleh JVM)

Melaksanakan antara muka Runnable

Jika anda menentang warisan dan/atau sudah mewarisi salah satu kelas lain, anda boleh menggunakan java.lang.Runnable. Di sini dalam kelas kami, kami melaksanakan antara muka ini dan melaksanakan kaedah run(), seperti dalam contoh itu. Anda hanya perlu mencipta lebih banyak objek Thread. Nampaknya lebih banyak baris lebih teruk. Tetapi kita tahu betapa berbahayanya warisan dan lebih baik untuk mengelakkannya dengan segala cara ;) Mari lihat:
/**
* Пример того, 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();
   }
}
Dan hasil pelaksanaan:

Thread-0
Thread-1
Thread-2

38. Apakah perbezaan antara proses dan benang?

50 Soalan dan Jawapan Temuduga Teras Java Teratas.  Bahagian 3 - 1Terdapat perbezaan berikut antara proses dan utas:
  1. Program dalam pelaksanaan dipanggil proses, manakala Thread ialah subset proses.
  2. Proses adalah bebas, manakala utas ialah subset proses.
  3. Proses mempunyai ruang alamat yang berbeza dalam ingatan, manakala benang mengandungi ruang alamat biasa.
  4. Penukaran konteks adalah lebih pantas antara utas berbanding dengan proses.
  5. Komunikasi antara proses adalah lebih perlahan dan lebih mahal daripada komunikasi antara benang.
  6. Sebarang perubahan dalam proses induk tidak menjejaskan proses anak, manakala perubahan dalam utas induk boleh menjejaskan urutan anak.

39. Apakah kelebihan multithreading?

50 Soalan dan Jawapan Temuduga Teras Java Teratas.  Bahagian 3 - 2
  1. Multithreading membenarkan aplikasi/program untuk sentiasa bertindak balas kepada input walaupun ia sudah menjalankan beberapa tugas latar belakang;
  2. Multithreading membolehkan anda menyelesaikan tugasan dengan lebih cepat kerana utas dilaksanakan secara bebas;
  3. Multithreading menyediakan penggunaan cache yang lebih baik kerana benang berkongsi sumber memori biasa;
  4. Multithreading mengurangkan jumlah pelayan yang diperlukan kerana satu pelayan boleh menjalankan berbilang thread secara serentak.

40. Apakah keadaan dalam kitaran hayat benang?

50 Soalan dan Jawapan Temuduga Teras Java Teratas.  Bahagian 3 - 3
  1. Baharu: Dalam keadaan ini, objek kelas Threaddicipta menggunakan pengendali baharu, tetapi benang tidak wujud. Benang tidak bermula sehingga kita memanggil start().
  2. Runnable: Dalam keadaan ini, benang sedia untuk dijalankan selepas memanggil kaedah mula (). Walau bagaimanapun, ia belum lagi dipilih oleh penjadual benang.
  3. Berjalan: Dalam keadaan ini, penjadual benang memilih benang daripada keadaan sedia dan ia berjalan.
  4. Menunggu/Disekat: Dalam keadaan ini, benang tidak berjalan tetapi masih hidup atau menunggu urutan lain selesai.
  5. Mati/Ditamatkan: Apabila kaedah keluar, run()benang berada dalam keadaan ditamatkan atau mati.

41. Adakah mungkin untuk memulakan benang dua kali?

Tidak, kami tidak boleh memulakan semula utas kerana setelah utas dimulakan dan dilaksanakan, ia masuk ke keadaan Mati. Jadi jika kita cuba menjalankan utas dua kali, ia akan membuang runtimeException " java.lang.IllegalThreadStateException ". Mari lihat:
class DoubleStartThreadExample extends Thread {

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

   /**
    * Запускаем тред дважды
    */
   public static void main(String[] args) {
       DoubleStartThreadExample doubleStartThreadExample = new DoubleStartThreadExample();
       doubleStartThreadExample.start();
       doubleStartThreadExample.start();
   }
}
Sebaik sahaja kerja mencapai permulaan kedua benang yang sama, maka akan ada pengecualian. Cuba sendiri ;) lebih baik melihat sekali daripada mendengar seratus kali.

42. Bagaimana jika anda memanggil kaedah run() secara terus tanpa memanggil kaedah start()?

Ya, run()sudah tentu anda boleh memanggil kaedah, tetapi ini tidak akan mencipta utas baharu dan melaksanakannya sebagai utas berasingan. Dalam kes ini, ia adalah objek mudah yang memanggil kaedah mudah. Jika kita bercakap tentang kaedah start(), maka ia adalah perkara yang berbeza. Dengan melancarkan kaedah ini, runtimeia melancarkan kaedah baharu dan ia, seterusnya, menjalankan kaedah kami ;) Jika anda tidak percaya saya, cubalah:
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();
   }
}
Dan output ke konsol akan menjadi seperti ini:

0123401234
Dapat dilihat bahawa tiada benang dicipta. Semuanya berfungsi seperti kelas biasa. Pertama kaedah kelas pertama berfungsi, kemudian yang kedua.

43. Apakah benang daemon?

50 Soalan dan Jawapan Temuduga Teras Java Teratas.  Bahagian 3 - 4Benang daemon (selepas ini dirujuk sebagai benang daemon) ialah benang yang melaksanakan tugas di latar belakang berhubung dengan benang lain. Iaitu, tugasnya adalah untuk melaksanakan tugas tambahan yang perlu dilakukan hanya bersempena dengan utas (utama) yang lain. Terdapat banyak benang daemon yang berjalan secara automatik, seperti Pengumpul Sampah, pemuktamad, dsb.

Mengapa Java menutup benang daemon?

Satu-satunya tujuan utas daemon ialah ia menyediakan perkhidmatan kepada utas pengguna untuk tugas sokongan latar belakang. Oleh itu, jika utas utama telah selesai, maka runtime secara automatik menutup semua utas daemonnya.

Kaedah untuk bekerja dalam kelas Thread

Kelas java.lang.Threadmenyediakan dua kaedah untuk bekerja dengan daemon benang:
  1. public void setDaemon(boolean status)- menunjukkan bahawa ini akan menjadi benang daemon. Lalai ialah false, yang bermaksud bahawa benang bukan daemon akan dibuat melainkan dinyatakan secara berasingan.
  2. public boolean isDaemon()- pada asasnya ini adalah pengambil untuk pembolehubah daemonyang kami tetapkan menggunakan kaedah sebelumnya.
Contoh:
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();
   }
}
Output konsol:

демон?.. true
демон?.. false
демон?.. false
daemon thread
user thread
user thread
Daripada output kita melihat bahawa di dalam benang itu sendiri, menggunakan currentThread()kaedah statik, kita boleh mengetahui benang mana di satu pihak, sebaliknya, jika kita mempunyai rujukan kepada objek benang ini, kita boleh mengetahui langsung daripadanya. Ini memberikan fleksibiliti yang diperlukan dalam konfigurasi.

44. Adakah mungkin untuk menjadikan benang sebagai daemon selepas ia dicipta?

Tidak. Jika anda melakukan ini ia akan membuang pengecualian IllegalThreadStateException. Oleh itu, kita hanya boleh mencipta benang daemon sebelum ia bermula. Contoh:
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);
   }
}
Output konsol:

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

45. Apakah itu shutdownhook?

Shutdownhook ialah utas yang dipanggil secara tersirat sebelum JVM (Java Virtual Machine) dimatikan. Jadi kita boleh menggunakannya untuk membersihkan sumber atau menyimpan keadaan apabila Mesin Maya Java dimatikan secara normal atau secara tiba-tiba. Kita boleh menambah shutdown hookmenggunakan kaedah berikut:
Runtime.getRuntime().addShutdownHook(new ShutdownHookThreadExample());
Seperti yang ditunjukkan dalam contoh:
/**
* Программа, которая показывает 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();
       }
   }
}
Output konsol:

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

46. ​​Apakah itu penyegerakan?

Penyegerakan dalam Java ialah keupayaan untuk mengawal akses berbilang benang kepada mana-mana sumber yang dikongsi. Apabila beberapa utas cuba melaksanakan tugas yang sama, terdapat kemungkinan hasil yang salah, jadi untuk mengatasi masalah ini, Java menggunakan penyegerakan, yang mana hanya satu utas boleh berfungsi pada satu masa. Penyegerakan boleh dicapai dalam tiga cara:
  • Kaedah penyegerakan
  • Dengan menyegerakkan blok tertentu
  • Penyegerakan statik

Penyegerakan kaedah

Kaedah disegerakkan digunakan untuk mengunci objek untuk sebarang sumber yang dikongsi. Apabila benang memanggil kaedah yang disegerakkan, ia secara automatik memperoleh kunci pada objek itu dan melepaskannya apabila benang menyelesaikan tugasnya. Untuk menjadikannya berfungsi, anda perlu menambah kata kunci yang disegerakkan . Mari lihat bagaimana ini berfungsi dengan contoh:
/**
* Пример, где мы синхронизируем метод. То есть добавляем ему слово 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);
   }
}
Dan output ke konsol:

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

Blok penyegerakan

Blok disegerakkan boleh digunakan untuk melakukan penyegerakan pada mana-mana sumber kaedah tertentu. Katakan bahawa dalam kaedah yang besar (ya, ya, anda tidak boleh menulis perkara sedemikian, tetapi kadang-kadang ia berlaku) anda perlu menyegerakkan hanya sebahagian kecil, atas sebab tertentu. Jika anda meletakkan semua kod kaedah dalam blok disegerakkan, ia akan berfungsi sama seperti kaedah disegerakkan. Sintaks kelihatan seperti ini:
synchronized (“an object для блокировки”) {
   // сам code, который нужно защитить
}
Untuk tidak mengulangi contoh sebelumnya, kami akan membuat utas melalui kelas tanpa nama - iaitu, dengan serta-merta melaksanakan antara muka Runnable.
/**
* Вот 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();
   }
}

}
dan output ke konsol

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

Penyegerakan statik

Jika anda membuat kaedah statik disegerakkan, kunci akan berada pada kelas, bukan pada objek. Dalam contoh ini, kami menggunakan kata kunci disegerakkan pada kaedah statik untuk melaksanakan penyegerakan statik:
/**
* Вот 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();
   }
}
dan output ke konsol:

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

47. Apakah pembolehubah yang tidak menentu?

Kata kunci volatiledigunakan dalam pengaturcaraan berbilang benang untuk menyediakan keselamatan benang kerana pengubahsuaian kepada satu pembolehubah boleh ubah kelihatan kepada semua utas lain, jadi satu pembolehubah boleh digunakan oleh satu utas pada satu masa. Menggunakan kata kunci, volatileanda boleh menjamin bahawa pembolehubah akan selamat untuk benang dan akan disimpan dalam memori kongsi dan benang tidak akan membawanya ke dalam cache mereka. Bagaimana rupanya?
private volatile AtomicInteger count;
Kami hanya menambah pembolehubah volatile. Tetapi ini tidak bermakna keselamatan benang lengkap... Lagipun, operasi mungkin bukan atom pada pembolehubah. Tetapi anda boleh menggunakan Atomickelas yang melaksanakan operasi secara atom, iaitu, dalam satu pelaksanaan oleh pemproses. Banyak kelas sedemikian boleh didapati dalam pakej java.util.concurrent.atomic.

48. Apakah kebuntuan

Kebuntuan di Jawa adalah sebahagian daripada multithreading. Kebuntuan boleh berlaku dalam situasi di mana benang menunggu pada kunci objek yang diperoleh oleh benang lain, dan benang kedua menunggu pada kunci objek yang diperoleh oleh benang pertama. Oleh itu, kedua-dua utas ini menunggu antara satu sama lain dan tidak akan terus melaksanakan kod mereka. 50 Soalan dan Jawapan Temuduga Teras Java Teratas.  Bahagian 3 - 5Mari kita lihat Contoh di mana terdapat kelas yang melaksanakan Runnable. Ia menerima dua sumber dalam pembinanya. Di dalam kaedah run(), ia memerlukan kunci untuk mereka satu demi satu, jadi jika anda mencipta dua objek kelas ini dan memindahkan sumber dalam susunan yang berbeza, anda boleh dengan mudah menghadapi kunci:
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);
           }
       }
   }
}
Output konsol:

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

49. Bagaimana untuk mengelakkan kebuntuan?

Berdasarkan apa yang kita tahu bagaimana kebuntuan berlaku, kita boleh membuat beberapa kesimpulan...
  • Seperti yang ditunjukkan dalam contoh di atas, kebuntuan itu disebabkan oleh sarang kunci. Iaitu, di dalam satu kunci terdapat satu lagi atau lebih. Anda boleh mengelakkan ini dengan cara berikut - bukannya bersarang, anda perlu menambah abstraksi baharu di atas dan memberikan kunci ke tahap yang lebih tinggi, dan mengalih keluar kunci bersarang.
  • Lebih banyak menghalang, lebih besar kemungkinan akan berlaku kebuntuan. Oleh itu, setiap kali anda menambah kunci, anda perlu memikirkan sama ada ia benar-benar diperlukan dan sama ada menambah yang baharu boleh dielakkan.
  • Kegunaan Thread.join(). Kebuntuan juga boleh dilakukan apabila satu benang sedang menunggu untuk yang lain. Untuk mengelakkan masalah ini, anda mungkin mempertimbangkan untuk menetapkan had masa pada join()kaedah tersebut.
  • Jika kita mempunyai satu benang, tidak akan ada kebuntuan ;)

50. Apakah syarat perlumbaan?

Jika dalam perlumbaan sebenar kereta beraksi, maka dalam terminologi perlumbaan multi-threading, benang beraksi dalam perlumbaan. Tapi kenapa? Terdapat dua utas yang sedang berjalan dan yang boleh mempunyai akses kepada objek yang sama. Dan mereka boleh cuba mengemas kini keadaan pada masa yang sama. Setakat ini semuanya jelas, bukan? Jadi benang berfungsi sama ada secara selari sebenar (jika terdapat lebih daripada satu teras dalam pemproses) atau selari secara bersyarat, apabila pemproses memperuntukkan tempoh masa yang singkat. Dan kami tidak boleh mengawal proses ini, jadi kami tidak dapat menjamin bahawa apabila satu utas membaca data daripada objek, ia akan mempunyai masa untuk mengubahnya SEBELUM beberapa utas lain melakukannya. Masalah seperti ini berlaku apabila gabungan ujian-dan-tindakan ini berlalu. Apakah maksudnya? Sebagai contoh, kita mempunyai ifungkapan dalam badan yang mana keadaan itu sendiri berubah, iaitu:
int z = 0;

// проверь
if (z < 5) {
//действуй
   z = z + 5;
}
Jadi mungkin terdapat situasi apabila dua utas secara serentak memasukkan blok kod ini pada masa z masih sama dengan sifar dan bersama-sama mereka menukar nilai ini. Dan pada akhirnya kita tidak akan mendapat nilai yang diharapkan sebanyak 5, tetapi 10. Bagaimana untuk mengelakkan ini? Anda perlu mengunci sebelum dan selepas pelaksanaan. Iaitu, untuk urutan pertama memasuki blok if, lakukan semua tindakan, ubahnya, zdan hanya kemudian berikan peluang seterusnya untuk melakukan ini. Tetapi benang seterusnya tidak akan memasuki blok if, kerana zia sudah sama dengan 5:
// получить блокировку для z
if (z < 5) {
   z = z + 5;
}
// выпустить из блокировки z
===================================================

Daripada keluaran

Saya ingin mengucapkan terima kasih kepada semua yang membaca hingga habis. Ia adalah perjalanan yang panjang dan anda berjaya! Tidak semuanya mungkin jelas. Ini baik. Sebaik sahaja saya mula belajar Java, saya tidak dapat membungkus kepala saya tentang apa itu pembolehubah statik. Tetapi tidak ada, saya tidur dengan pemikiran ini, membaca beberapa sumber lagi dan akhirnya faham. Persediaan untuk temu duga adalah lebih kepada perkara akademik berbanding praktikal. Oleh itu, sebelum setiap temu duga, anda perlu mengulang dan menyegarkan ingatan anda tentang perkara-perkara yang mungkin anda jarang gunakan.

Dan seperti biasa, pautan berguna:

Terima kasih semua kerana membaca, Jumpa anda tidak lama lagi) Profil saya di GitHub
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION