1. Ikhtisar topik
Thread adalah unit eksekusi dasar untuk eksekusi program. Ketika sistem operasi (tidak termasuk sistem operasi thread tunggal, seperti DOS awal Microsoft) menjalankan suatu program, sebuah proses akan dibuat dalam sistem, dan dalam proses ini, setidaknya satu thread harus dibuat (thread ini disebut thread utama). thread).thread) sebagai titik masuk untuk menjalankan program ini. Oleh karena itu, setiap program yang berjalan di sistem operasi memiliki setidaknya satu thread utama.
Proses dan thread adalah dua model operasi penting dalam sistem operasi modern. Terdapat beberapa proses dalam sistem operasi, termasuk proses sistem (proses yang dibuat secara internal oleh sistem operasi) dan proses pengguna (proses yang dibuat oleh program pengguna); Tidak ada memori bersama antar proses, yang berarti bahwa proses dalam sistem berjalan di ruang memori independennya sendiri. Thread dalam suatu proses dapat berbagi ruang memori yang dialokasikan oleh sistem untuk proses tersebut.
Utas tidak hanya dapat berbagi memori proses, tetapi juga memiliki ruang memorinya sendiri. Ruang memori ini juga disebut tumpukan utas. Ini dialokasikan oleh sistem ketika utas dibuat data yang digunakan di dalam thread, seperti tumpukan thread. Variabel yang ditentukan dalam fungsi eksekusi.
Catatan: Setiap thread akan menjalankan suatu fungsi saat dibuat. Fungsi ini disebut fungsi eksekusi thread. Fungsi ini juga dapat dianggap sebagai titik masuk thread (mirip dengan fungsi utama dalam program). Tidak peduli bahasa atau teknologi apa yang digunakan untuk membuat thread, fungsi ini harus dijalankan (ekspresi fungsi ini mungkin berbeda, tetapi akan selalu ada fungsi seperti itu). Misalnya, parameter ketiga dari fungsi API CreateThread yang digunakan untuk membuat thread di Windows adalah penunjuk fungsi eksekusi ini.
Setelah sistem operasi membagi proses menjadi beberapa thread, thread ini dapat dijalankan secara bersamaan di bawah pengelolaan sistem operasi, sehingga sangat meningkatkan efisiensi jalannya program. Meskipun eksekusi thread terlihat seperti beberapa thread yang dieksekusi secara bersamaan dari perspektif makro, sebenarnya ini hanyalah penutup-nutupan dari sistem operasi. Karena CPU hanya dapat menjalankan satu instruksi dalam satu waktu, tidak mungkin menjalankan dua tugas secara bersamaan pada komputer dengan satu CPU. Untuk meningkatkan efisiensi jalannya program, sistem operasi akan menghapus thread saat idle dan membiarkan thread lain mengeksekusinya. Alasan mengapa kita melihat beberapa thread dieksekusi pada waktu yang sama di permukaan adalah karena waktu untuk berpindah antar thread yang berbeda sangat singkat, dan dalam keadaan normal peralihan sangat sering terjadi. Misalkan kita mempunyai thread A dan B. Pada saat dijalankan, mungkin setelah A dijalankan selama 1 milidetik, setelah beralih ke B, B dijalankan selama 1 milidetik lagi, lalu beralih ke A, dan A dijalankan selama 1 milidetik lagi. Karena 1 milidetik sulit dipahami oleh orang awam, di permukaan sepertinya A dan B dieksekusi pada waktu yang sama, namun kenyataannya A dan B dieksekusi secara bergantian.
2. Manfaat benang bagi kita
Penggunaan thread yang tepat dapat mengurangi biaya pengembangan dan pemeliharaan dan bahkan meningkatkan kinerja aplikasi yang kompleks. Misalnya, dalam aplikasi GUI, peristiwa dapat diproses dengan lebih baik melalui sifat thread yang tidak sinkron; dalam program server aplikasi, beberapa thread dapat dibuat untuk menangani permintaan klien. Thread bahkan dapat menyederhanakan implementasi mesin virtual. Misalnya, pengumpul sampah Java Virtual Machine (JVM) biasanya berjalan di satu atau lebih thread. Oleh karena itu, penggunaan thread akan meningkatkan aplikasi kita dalam lima aspek berikut:
1. Manfaatkan sepenuhnya sumber daya CPU
Kebanyakan komputer di dunia sekarang hanya memiliki satu CPU. Oleh karena itu, sangat penting untuk memanfaatkan sumber daya CPU sepenuhnya. Saat menjalankan program single-thread, CPU mungkin menganggur saat program diblokir. Hal ini akan menyebabkan banyak pemborosan sumber daya komputasi. Menggunakan multi-threading dalam suatu program dapat menjalankan thread lain ketika thread sedang tidur atau diblokir dan CPU dalam keadaan idle. Dengan cara ini, CPU sulit untuk menganggur. Oleh karena itu, sumber daya CPU dimanfaatkan sepenuhnya.
2. Sederhanakan model pemrograman
Jika program hanya menyelesaikan satu tugas, maka cukup tulis program single-thread dan tulis kode sesuai dengan langkah-langkah untuk melakukan tugas tersebut. Namun untuk menyelesaikan banyak tugas, jika Anda masih menggunakan satu thread, Anda harus menentukan dalam program apakah dan kapan setiap tugas harus dijalankan. Misalnya, ini menampilkan jam, menit, dan detik dari sebuah jam. Jika Anda menggunakan utas tunggal, Anda harus menilai waktu rotasi dan sudut ketiga penunjuk ini satu per satu dalam loop. Jika tiga thread digunakan untuk menangani tampilan ketiga pointer ini, maka itu berarti melakukan tugas terpisah untuk setiap thread. Hal ini membantu pengembang memahami dan memelihara program.
3. Menyederhanakan pemrosesan kejadian asinkron
Ketika aplikasi server menerima koneksi klien yang berbeda, cara paling sederhana untuk menanganinya adalah dengan membuat thread untuk setiap koneksi klien. Thread yang mendengarkan kemudian masih bertanggung jawab untuk mendengarkan permintaan dari klien. Jika aplikasi semacam ini diproses oleh satu thread, ketika thread yang mendengarkan menerima permintaan klien, ia mulai membaca data yang dikirim oleh klien. Setelah membaca data, metode baca diblokir, yaitu thread ini akan Tidak dapat lagi mendengarkan permintaan klien. Jika Anda ingin menangani beberapa permintaan klien dalam satu thread, Anda harus menggunakan koneksi Socket non-pemblokiran dan I/O asinkron. Namun, penggunaan I/O asinkron lebih sulit dikendalikan dan lebih rawan kesalahan dibandingkan menggunakan I/O sinkron. Oleh karena itu, kejadian asinkron seperti beberapa permintaan dapat ditangani dengan lebih mudah menggunakan multithreading dan I/O sinkron.
4. Jadikan GUI lebih efisien
Saat menggunakan thread tunggal untuk memproses kejadian GUI, loop harus digunakan untuk memindai kejadian GUI yang mungkin terjadi kapan saja. Di dalam loop, selain memindai kejadian GUI, kode program lain harus dijalankan. Jika kode terlalu panjang, kejadian GUI akan "dibekukan" hingga kode dijalankan.
Dalam kerangka GUI modern (seperti SWING, AWT, dan SWT), thread pengiriman peristiwa (EDT) terpisah digunakan untuk memindai peristiwa GUI. Saat kita menekan sebuah tombol, fungsi event klik tombol tersebut akan dipanggil di thread pengiriman event ini. Karena tugas EDT hanya memindai kejadian GUI, respons terhadap kejadian dengan cara ini sangat cepat.
5. Penghematan biaya
Umumnya ada tiga metode untuk meningkatkan efisiensi pelaksanaan program:
(1) Meningkatkan jumlah CPU di komputer.
(2) Mulai beberapa proses untuk satu program
(3) Gunakan banyak proses dalam program.
Cara pertama adalah cara yang paling mudah dilakukan, namun juga paling mahal. Metode ini tidak memerlukan modifikasi program. Secara teori, program apa pun dapat menggunakan metode ini untuk meningkatkan efisiensi eksekusi. Meskipun metode kedua tidak memerlukan pembelian perangkat keras baru, tidak mudah untuk berbagi data. Jika tugas yang harus diselesaikan oleh program ini memerlukan berbagi data, metode ini tidak nyaman, dan memulai beberapa thread akan menghabiskan banyak sistem. sumber daya. Cara ketiga hanya menutupi kekurangan cara pertama, sekaligus mewarisi kelebihannya. Dengan kata lain, tidak perlu membeli CPU, juga tidak akan menghabiskan banyak sumber daya sistem dengan memulai terlalu banyak thread (secara default, ruang memori yang digunakan oleh sebuah thread jauh lebih kecil daripada ruang memori yang digunakan oleh suatu proses) .Multiple), dan multi-threading dapat mensimulasikan mode berjalan beberapa CPU. Oleh karena itu, menggunakan multi-threading adalah cara termurah untuk meningkatkan efisiensi eksekusi program.
3. Model utas Java
Karena Java adalah bahasa yang murni berorientasi objek, model threading Java juga berorientasi objek. Java merangkum semua fungsi thread yang diperlukan melalui kelas Thread. Untuk membuat thread, harus ada fungsi eksekusi thread. Fungsi eksekusi thread ini sesuai dengan metode run dari kelas Thread. Kelas Thread juga memiliki metode start, yang bertanggung jawab untuk membuat thread, yang setara dengan memanggil fungsi pembuatan thread Windows CreateThread. Ketika metode start dipanggil, jika thread berhasil dibuat, metode run dari kelas Thread secara otomatis dipanggil. Oleh karena itu, setiap kelas Java yang mewarisi Thread dapat membuat thread melalui metode awal kelas Thread. Jika Anda ingin menjalankan fungsi eksekusi thread Anda sendiri, Anda harus mengganti metode run dari kelas Thread.
Selain kelas Thread dalam model thread Java, ada juga antarmuka Runnable yang mengidentifikasi apakah kelas Java dapat digunakan sebagai kelas thread. Antarmuka ini hanya menjalankan satu metode abstrak, yaitu fungsi eksekusi thread Java model benang. Oleh karena itu, satu-satunya kriteria untuk kelas thread adalah apakah kelas tersebut mengimplementasikan metode run pada antarmuka Runnable. Dengan kata lain, kelas dengan fungsi eksekusi thread adalah kelas thread.
Seperti terlihat di atas, ada dua cara untuk membuat thread di Java, yang pertama adalah dengan mewarisi kelas Thread, dan yang lainnya adalah dengan mengimplementasikan antarmuka Runnable dan membuat thread melalui Thread dan kelas yang mengimplementasikan Runnable. kedua metode ini pada dasarnya dikatakan sebagai sebuah metode, yaitu thread dibuat melalui kelas Thread dan metode run dijalankan. Namun perbedaan besarnya adalah thread dibuat dengan mewarisi kelas Thread. Meskipun lebih mudah diimplementasikan, karena Java tidak mendukung pewarisan berganda, jika kelas thread ini mewarisi Thread, maka tidak dapat mewarisi kelas lain metode untuk membuat thread dengan mengimplementasikan antarmuka Runnable, sehingga kelas thread dapat mewarisi kelas terkait bisnis alih-alih kelas Thread bila diperlukan.