JavaRush /Blog Java /Random-MS /Multithreading: Apakah Kaedah Kelas Benang Lakukan

Multithreading: Apakah Kaedah Kelas Benang Lakukan

Diterbitkan dalam kumpulan
hello! Hari ini kita terus bercakap tentang multithreading. Mari kita lihat kelas Thread dan cara beberapa kaedahnya berfungsi. Sebelum ini, apabila kami mempelajari kaedah kelas, kami selalunya menulisnya seperti ini: "nama kaedah" -> "apa yang dilakukannya."
Multithreading: apa yang dilakukan oleh kaedah kelas Thread - 1
Ini tidak akan berfungsi dengan kaedah Thread :) Logik mereka lebih rumit, dan tanpa beberapa contoh adalah mustahil untuk difahami.

Kaedah thread.start().

Mari kita mulakan dengan pengulangan. Seperti yang anda mungkin ingat, anda boleh mencipta urutan dengan mewarisi kelas anda daripada kelas Threaddan mengatasi kaedah di dalamnya run(). Tetapi, sudah tentu, ia tidak akan bermula dengan sendirinya. Untuk melakukan ini, kami memanggil kaedah pada objek kami start(). Multithreading: apa yang dilakukan oleh kaedah kelas Thread - 2Mari kita ingat contoh dari kuliah sebelumnya:
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();
       }
   }
}
Sila ambil perhatian: untuk memulakan utas, anda mesti memanggil kaedah khasstart(), bukanrun()! Ini adalah kesilapan yang mudah dilakukan, terutamanya apabila mula-mula belajar multithreading. Jika dalam contoh kami anda memanggil kaedah objekrun()dan bukannyastart(), hasilnya akan seperti ini:
public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {
           MyFirstThread thread = new MyFirstThread();
           thread.run();
       }
   }
}
Thread-0 thread dilaksanakan Thread-1 thread executed Thread-2 thread executed Thread-3 thread executed Thread-4 thread dilaksanakan Thread-5 thread dilaksanakan Thread-6 thread dilaksanakan Thread-7 thread executed Thread-8 thread executed Thread-9 thread dilaksanakan Lihat urutan output: semuanya berjalan dengan ketat. Pelik kan? Kami tidak biasa dengan ini, kerana kami sudah tahu bahawa susunan urutan dilancarkan dan dilaksanakan ditentukan oleh superintelligence dalam sistem pengendalian kami - penjadual benang. Mungkin saya hanya bernasib baik? Sudah tentu, ia bukan soal nasib. Anda boleh mengesahkan ini dengan menjalankan program beberapa kali lagi. Intinya ialah memanggil kaedah secara langsungrun()tidak ada kaitan dengan multithreading. Dalam kes ini, program akan dilaksanakan dalam utas utama - yang kaedahnya dilaksanakanmain(). Ia hanya akan mengeluarkan 10 baris secara berurutan ke konsol dan itu sahaja. Tiada 10 utas akan bermula. Oleh itu, ingatlah untuk masa depan dan sentiasa periksa diri anda. Jika anda mahu ia dilakukanrun(), hubungi iastart(). Jom teruskan.

Kaedah thread.sleep().

Untuk menjeda pelaksanaan utas semasa untuk beberapa lama, gunakan sleep(). Multithreading: apa yang dilakukan oleh kaedah kelas Thread - 3Kaedah ini sleep()mengambil sebagai parameter bilangan milisaat, iaitu, masa yang mana benang perlu ditidurkan.
public class Main {

   public static void main(String[] args) throws InterruptedException {

       long start = System.currentTimeMillis();

       Thread.sleep(3000);

       System.out.println(" - Сколько я проспал? \n - " + ((System.currentTimeMillis()-start)) / 1000 + " секунды");

   }
}
Output konsol: - Berapa lama saya tidur? - 3 saat Sila ambil perhatian: kaedah ini sleep()adalah statik: ia meletakkan benang semasa tidur. Iaitu, yang sedang bekerja pada masa ini. Satu lagi nuansa penting: aliran dalam keadaan tidur boleh terganggu. Dalam kes ini, pengecualian akan berlaku dalam program InterruptedException. Kami akan melihat contoh di bawah. By the way, apa yang berlaku selepas benang "bangun"? Adakah ia akan meneruskan pelaksanaannya dengan segera dari tempat ia berhenti? Tidak. Selepas urutan bangun—apabila masa berlalu sebagai hujah untuk tamat tempoh Thread.sleep()—ia memasuki keadaan boleh jalan . Walau bagaimanapun, ini tidak bermakna bahawa penjadual benang akan menjalankannya. Ada kemungkinan ia akan memberi keutamaan kepada beberapa benang "tidak tidur" lain, dan benang "baru terbangun" kami akan terus berfungsi sedikit kemudian. Pastikan anda ingat: "bangun tidak bermakna terus bekerja pada saat itu!"

Kaedah thread.join().

Многопоточность: что делают методы класса Thread - 4Kaedah ini join()menangguhkan pelaksanaan utas semasa sehingga utas lain selesai. Jika kita mempunyai 2 utas, t1dan t2, dan kita tulis -
t1.join()
t2tidak akan mula bekerja sehingga t1 telah menyelesaikan kerjanya. Kaedah ini join()boleh digunakan untuk memastikan urutan pelaksanaan benang. Mari kita lihat kerja join()menggunakan contoh:
public class ThreadExample extends Thread {

   @Override
   public void run() {

       System.out.println("Начало работы потока " + getName());

       try {
           Thread.sleep(5000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       System.out.println("Поток " + getName() +  " завершил работу.");
   }
}


public class Main {

   public static void main(String[] args) throws InterruptedException {

       ThreadExample t1 = new ThreadExample();
       ThreadExample t2 = new ThreadExample();

       t1.start();


 /*Второй поток t2 начнет выполнение только после того, How будет завершен
       (or бросит исключение) первый поток - t1*/
       try {
           t1.join();
       } catch (InterruptedException e) {
           e.printStackTrace();
       }

       t2.start();

       //Главный поток продолжит работу только после того, How t1 и t2 завершат работу
       try {
           t1.join();
           t2.join();
       } catch (InterruptedException e) {
           e.printStackTrace();
       }

       System.out.println("Все потоки закончor работу, программа завершена");

   }
}
Kami telah mencipta kelas yang mudah ThreadExample. Tugasnya adalah untuk memaparkan mesej pada skrin tentang permulaan kerja, kemudian tertidur selama 5 saat dan pada akhirnya memaklumkan tentang penyiapan kerja. Tiada yang rumit. Logik utama terkandung dalam kelas Main. Lihat komen: menggunakan kaedah, join()kami berjaya mengawal urutan pelaksanaan benang. Jika anda masih ingat permulaan topik, penjadual benang melakukan ini. Dia melancarkannya mengikut budi bicaranya sendiri: berbeza setiap kali. Di sini, menggunakan kaedah, kami memastikan bahawa pertama-tama utas akan dilancarkan dan dilaksanakan t1, kemudian utas t2, dan hanya selepas mereka utas utama pelaksanaan program. Teruskan. Dalam program sebenar, anda akan sering menghadapi situasi apabila anda perlu mengganggu pelaksanaan beberapa utas. Sebagai contoh, utas kami sedang berjalan, tetapi ia sedang menunggu acara atau syarat tertentu untuk dipenuhi. Jika ini berlaku, ia berhenti. Ia mungkin logik jika terdapat beberapa kaedah seperti stop(). Walau bagaimanapun, semuanya tidak begitu mudah. Pada suatu masa dahulu, kaedah Thread.stop()dalam Java sebenarnya wujud dan membolehkan anda mengganggu kerja benang. Tetapi kemudian ia telah dialih keluar dari perpustakaan Java. Anda boleh melihatnya dalam dokumentasi Oracle dan melihat bahawa ia ditandakan sebagai tidak digunakan lagi . kenapa? Kerana ia hanya menghentikan aliran tanpa sebarang kerja tambahan. Sebagai contoh, benang boleh berfungsi dengan data dan mengubah sesuatu di dalamnya. Kemudian dia tiba-tiba tersingkir stop()di tengah-tengah kerja - dan itu sahaja. Tiada penutupan yang betul, tiada pembebasan sumber, malah tiada pengendalian ralat - semua ini tidak berlaku. Kaedah itu stop(), untuk membesar-besarkan, hanya memusnahkan segala-galanya di laluannya. Operasinya boleh dibandingkan dengan cara seseorang menarik plag dari soket untuk mematikan komputer. Ya, anda boleh mencapai hasil yang diinginkan. Tetapi semua orang memahami bahawa dalam beberapa minggu komputer tidak akan berkata "terima kasih" untuk ini. Atas sebab ini, logik untuk mengganggu benang di Jawa telah diubah, dan kini kaedah khas digunakan - interrupt().

Kaedah thread.interrupt().

Apa yang berlaku jika anda memanggil kaedah interrupt() pada benang ? Terdapat 2 pilihan:
  1. Jika objek berada dalam keadaan menunggu pada masa itu, contohnya, joinatau sleep, menunggu akan terganggu dan program akan membuang InterruptedException.
  2. Jika urutan berada dalam keadaan berfungsi pada masa itu, bendera boolean objek akan ditetapkan interrupted.
Tetapi kita perlu menyemak objek untuk nilai bendera ini dan menyelesaikan kerja dengan betul sendiri! Untuk tujuan ini, kelas Threadmempunyai kaedah khas - boolean isInterrupted(). Mari kita kembali kepada contoh jam dari kuliah kursus utama. Untuk kemudahan, ia dipermudahkan sedikit:
public class Clock extends Thread {

   public static void main(String[] args) throws InterruptedException {
       Clock clock = new Clock();
       clock.start();

       Thread.sleep(10000);
       clock.interrupt();
   }

   public void run() {
       Thread current = Thread.currentThread();

       while (!current.isInterrupted())
       {
           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               System.out.println("Работа потока была прервана");
               break;
           }
           System.out.println("Tik");
       }
   }
}
Dalam kes kami, jam bermula dan mula berdetik setiap saat. Pada saat ke-10 kami mengganggu aliran jam. Seperti yang anda sedia maklum, jika urutan yang kami cuba ganggu berada dalam salah satu keadaan menunggu, ini menghasilkan InterruptedException. Pengecualian jenis ini ialah pengecualian yang diperiksa, jadi ia boleh ditangkap dengan mudah dan logik penamatan program kami dilaksanakan. Itulah yang kami lakukan. Berikut ialah hasil kami: Tik Tik Tik Tik Tik Tik Tik Tik Tik Kerja benang terganggu. Ini mengakhiri pengenalan kami kepada kaedah utama kelas Thread. Untuk mengukuhkan pengetahuan anda, anda boleh menonton kuliah video ini tentang multithreading:
ia akan berfungsi sebagai bahan tambahan yang sangat baik! Pada akhirnya, selepas gambaran keseluruhan kaedah, ia memberitahu dengan tepat apa yang akan kita lalui seterusnya dalam kursus :) Semoga berjaya!
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION