1. Buat utas
Ada dua cara untuk membuat thread di Java: menggunakan kelas Thread dan menggunakan antarmuka Runnable. Saat menggunakan antarmuka Runnable, Anda perlu membuat instance Thread. Oleh karena itu, baik Anda membuat thread melalui kelas Thread atau antarmuka Runnable, Anda harus membuat instance kelas Thread atau subkelasnya. Konstruktor utas:
Metode 1: Mewarisi kelas Thread dan mengganti metode run
}
}
kelas Demo memperluas Thread{
menjalankan kekosongan publik(){
untuk(int i=0;i<60;i++){
System.out.println(Thread.currentThread().getName()+i);
}
}
}
Sama seperti manusia dilahirkan, tua, sakit dan mati, benang juga harus melalui empat keadaan berbeda: mulai (menunggu), berlari, menggantung dan berhenti. Keempat keadaan ini dapat dikontrol melalui metode di kelas Thread. Metode yang terkait dengan empat keadaan di kelas Thread diberikan di bawah ini.
Thread tidak mengeksekusi kode dalam metode run segera setelah dibuat, tetapi berada dalam status menunggu. Saat thread berada dalam status menunggu, Anda dapat mengatur berbagai atribut thread melalui metode kelas Thread, seperti prioritas thread (setPriority), nama thread (setName), dan jenis thread (setDaemon).
Ketika metode start dipanggil, thread mulai mengeksekusi kode dalam metode run. Thread memasuki status berjalan. Anda dapat menggunakan metode isAlive dari kelas Thread untuk menentukan apakah thread sedang berjalan. Ketika thread dalam keadaan berjalan, isAlive mengembalikan nilai true. Ketika isAlive mengembalikan false, thread mungkin dalam keadaan menunggu atau dalam keadaan berhenti. Kode berikut menunjukkan peralihan antara tiga keadaan pembuatan thread, berjalan dan berhenti, dan menghasilkan nilai kembalian isAlive yang sesuai.
Setelah thread mulai mengeksekusi metode run, thread tidak akan keluar hingga metode run selesai. Namun, selama eksekusi thread, ada dua metode yang dapat digunakan untuk menghentikan sementara eksekusi thread. Kedua metode ini adalah suspend dan sleep. Setelah menggunakan penangguhan untuk menangguhkan thread, Anda dapat mengaktifkannya melalui metode resume. Setelah menggunakan sleep untuk membuat thread tertidur, thread hanya dapat berada dalam status siap setelah waktu yang ditentukan (setelah thread tidur berakhir, thread mungkin tidak langsung dijalankan, tetapi hanya memasuki status siap, menunggu sistem menjadwalkan) .
Ada dua hal yang perlu diperhatikan saat menggunakan metode tidur:
1. Metode tidur memiliki dua bentuk kelebihan beban. Salah satu bentuk kelebihan beban tidak hanya dapat mengatur milidetik, tetapi juga nanodetik (1.000.000 nanodetik setara dengan 1 milidetik). Namun, mesin virtual Java pada sebagian besar platform sistem operasi tidak akurat dalam nanodetik. Oleh karena itu, jika nanodetik disetel untuk tidur, mesin virtual Java akan mengambil milidetik paling dekat dengan nilai ini.
2. Melempar atau mencoba{...}menangkap{...} harus digunakan saat menggunakan metode tidur. Karena metode run tidak dapat menggunakan lemparan, Anda hanya dapat menggunakan try{...}catch{...}. Ketika thread sedang tidur dan metode interupsi digunakan untuk menginterupsi thread, sleep akan memunculkan InterruptedException. Metode tidur didefinisikan sebagai berikut:
Ada tiga cara untuk mengakhiri thread.
1. Gunakan tanda keluar untuk membuat thread keluar secara normal, yaitu thread berakhir ketika metode run selesai.
2. Gunakan metode stop untuk menghentikan thread secara paksa (metode ini tidak disarankan karena penghentian, seperti penangguhan dan melanjutkan, juga dapat memberikan hasil yang tidak terduga).
3. Gunakan metode interupsi untuk menginterupsi thread.
1. Hentikan thread menggunakan tanda keluar
Ketika metode run dijalankan, thread akan keluar. Namun terkadang metode yang dijalankan tidak pernah berakhir. Misalnya, thread digunakan dalam program server untuk memantau permintaan klien, atau tugas lain yang memerlukan pemrosesan siklik. Dalam hal ini, tugas-tugas ini biasanya ditempatkan dalam satu perulangan, seperti perulangan while. Jika Anda ingin loop berjalan selamanya, Anda dapat menggunakan while(true){...} untuk menanganinya. Tetapi jika Anda ingin membuat perulangan while keluar dalam kondisi tertentu, cara paling langsung adalah dengan menyetel tanda tipe boolean, dan menyetel tanda ini ke benar atau salah untuk mengontrol apakah perulangan while keluar. Contoh penghentian thread menggunakan tanda keluar diberikan di bawah ini.
Fungsi dari metode join adalah membuat thread eksekusi asinkron menjadi eksekusi sinkron. Artinya, ketika metode awal dari instance thread dipanggil, metode ini akan segera kembali. Jika Anda perlu menggunakan nilai yang dihitung oleh thread ini setelah memanggil metode awal, Anda harus menggunakan metode join. Jika Anda tidak menggunakan metode join, tidak ada jaminan bahwa ketika pernyataan yang mengikuti metode start dijalankan, thread akan dieksekusi. Setelah menggunakan metode join, program tidak akan melanjutkan eksekusi hingga thread ini keluar. Kode berikut menunjukkan penggunaan join.
3. Masalah keamanan multi-thread
Penyebab masalah: Ketika beberapa pernyataan beroperasi pada thread yang sama dan berbagi data, satu thread hanya mengeksekusi sebagian dari beberapa pernyataan. Sebelum eksekusi selesai, thread lain berpartisipasi dalam eksekusi, sehingga terjadi kesalahan data bersama.
Solusi: Untuk beberapa pernyataan yang beroperasi pada data bersama, hanya satu thread yang dapat dieksekusi. Selama proses eksekusi, thread lainnya tidak akan dieksekusi.
Blok kode sinkron:
}
}
}
}
menjalankan kekosongan publik(){
sementara(benar){
penjualanTiket();
}
}
}
Komunikasi antar thread
x=(x+1)%2;
}
}
}).awal();
Thread baru(Runnable baru(){
menjalankan kekosongan publik(){
sementara(benar){
hal.dapatkan();
}
}
}).awal();
}
}
/*
Zhang San....Laki-laki Zhang San....Laki-laki
lili....nv
lili....laki-laki Zhang San....nv
lili....laki-laki
*/
}
}
}).awal();
Thread baru(Runnable baru(){
menjalankan kekosongan publik(){
sementara(benar){
disinkronkan (p) {
hal.dapatkan();
}
}
}
}).awal();
}
}
/*
lili....nv
lili....nv
lili....nv
lili....nv
lili....nv
lili....nv
Zhang San....Laki-laki Zhang San....Laki-laki Zhang San....Laki-laki Zhang San....Laki-laki
*/
}
}
}).awal();
Thread baru(Runnable baru(){
menjalankan kekosongan publik(){
sementara(benar){
disinkronkan (p) {
jika(!bendera)
mencoba {
p.tunggu();
} tangkapan (InterruptedException e) {
// TODO Blok tangkapan yang dibuat secara otomatis
e.printStackTrace();
};
hal.dapatkan();
bendera =salah;
p.notifyAll();
}
}
}
}).awal();
}
}
}
Barang akhir g =Barang baru();
Thread baru(Runnable baru(){
menjalankan kekosongan publik(){
sementara(benar){
g.menghasilkan("barang");
}
}
}).awal();
Thread baru(Runnable baru(){
menjalankan kekosongan publik(){
sementara(benar){
g.konsumsi();
}
}
}).awal();
}
}
}
Barang akhir g =Barang baru();
Thread baru(Runnable baru(){
menjalankan kekosongan publik(){
sementara(benar){
g.menghasilkan("barang");
}
}
},"Produser No.1").start();
Thread baru(Runnable baru(){
menjalankan kekosongan publik(){
sementara(benar){
g.menghasilkan("barang");
}
}
},"Produser No.2").start();
Thread baru(Runnable baru(){
menjalankan kekosongan publik(){
sementara(benar){
g.konsumsi();
}
}
},"Konsumen No.1").start();
Thread baru(Runnable baru(){
menjalankan kekosongan publik(){
sementara(benar){
g.konsumsi();
}
}
},"Konsumen No. 2").start();
}
}
/*
Konsumen No. 2 yang dikonsumsi ****** Nomor produk: 48049
Produser Satu memproduksi....Nomor barang: 48050
Konsumen No. 1 yang dikonsumsi ****** Nomor produk: 48050
Produser Satu memproduksi....Nomor barang: 48051
Konsumen No. 2 yang dikonsumsi ****** Nomor produk: 48051
Produser No.2 memproduksi....Nomor barang: 48052
Konsumen No. 2 yang dikonsumsi ****** Nomor produk: 48052
Produser Satu memproduksi....Nomor barang: 48053
Konsumen No. 1 yang dikonsumsi ****** Nomor produk: 48053
Produser Satu memproduksi....Nomor barang: 48054
Konsumen No. 2 yang dikonsumsi ****** Nomor produk: 48054
Produser No.2 memproduksi....Nomor barang: 48055
Konsumen No. 2 yang dikonsumsi ****** Nomor produk: 48055
*/