Halo semuanya!
Kami meluncurkan aliran ketujuh dari kursus
Java Developer . Dalam lebih dari satu tahun keberadaan kursus ini, itu disempurnakan, diasah, yang baru ditambahkan yang melampaui waktu ini. Aliran yang sama berbeda dari yang lain karena kami memperkenalkan sistem baru langkah-langkah, memecah kursus menjadi tiga bagian dan sedikit meningkatkan durasi totalnya. Jadi sekarang tidak perlu kelelahan selama lima bulan berturut-turut untuk mendapatkan sertifikat, tetapi dengan tenang memilih periode dua bulan dan menjalani pelatihan. Tapi ini liriknya, mari kembali ke tradisi kita tentang berbagai utilitas sebelum peluncuran kursus.
Ayo pergi.
1. Ikhtisar
Wadah servlet Java (atau server web) multithreaded: beberapa permintaan ke servlet yang sama dapat dijalankan secara bersamaan. Karena itu, ketika menulis servlet, Anda harus mempertimbangkan kompetisi.
Seperti yang kami katakan sebelumnya, satu dan hanya satu instance servlet dibuat, dan untuk setiap permintaan baru, Servlet Container membuat utas baru untuk menjalankan metode doGet () atau doPost () dari servlet.
Secara default, servlets tidak aman, programmer harus mengurusnya sendiri. Dalam bab ini, kita akan membahas kompetisi servlet. Ini adalah konsep yang sangat penting, jadi fokuslah.
2. Ikhtisar utas

Utas adalah proses ringan yang memiliki tumpukan panggilannya sendiri dan mengakses data terbuka utas lainnya dalam proses yang sama (tumpukan bersama). Setiap utas memiliki cache sendiri.
Ketika kita mengatakan bahwa suatu program multithreaded, berarti bahwa instance yang sama dari suatu objek menghasilkan beberapa utas dan memproses elemen kode tunggal. Ini berarti bahwa beberapa aliran kontrol berturut-turut melewati blok memori yang sama. Dengan demikian, banyak utas mengeksekusi satu instance dari suatu program dan, oleh karena itu, berbagi variabel instance dan dapat mencoba membaca dan menulis variabel-variabel bersama ini.
Mari kita lihat contoh Java sederhana.
public class Counter { int counter=10; public void doSomething() { System.out.println(βInital Counter = β + counter); counter ++; System.out.println(βPost Increment Counter = β + counter); } }
Sekarang kita membuat dua thread Thread1 dan Thread2 untuk melakukan
doSomething()
. Akibatnya, ada kemungkinan bahwa:
- Thread1 membaca nilai penghitung 10
- Menampilkan Inital Counter = 10 dan akan bertambah
- Sebelum Thread1 menambah penghitung, Thread2 juga menambah penghitung, mengubah penghitung menjadi 11
- Akibatnya, Thread1 memiliki nilai penghitung 10, yang sudah usang
Skenario ini dimungkinkan dalam lingkungan multi-utas, seperti servlet, karena variabel instan dibagi oleh semua utas yang berjalan dalam instance yang sama.
3. Menulis servlet yang aman
Saya harap di bagian ini Anda akan memahami masalah yang saya coba tekankan. Jika Anda ragu, baca poin 2 lagi.
Ada beberapa poin yang perlu kita pertimbangkan saat menulis servlets.
Service()
, doGet()
, doPost()
atau, lebih umum, metode doXXX()
tidak boleh memperbarui atau memodifikasi variabel instance, karena variabel instance dibagi oleh semua utas dari instance yang sama.- Jika ada kebutuhan untuk memodifikasi variabel instan, maka lakukan dalam blok yang disinkronkan.
- Kedua aturan di atas berlaku untuk variabel statis juga karena keduanya juga umum.
- Variabel lokal selalu aman untuk thread.
- Objek permintaan dan respons aman untuk digunakan karena instance baru dibuat untuk setiap permintaan dalam servlet Anda dan, karenanya, untuk setiap utas yang berjalan di servlet Anda.
Berikut ini adalah dua pendekatan untuk memastikan keamanan benang:
a) Sinkronisasi blok tempat Anda memodifikasi instance atau variabel statis (lihat cuplikan kode di bawah).
Kami menyarankan Anda menyinkronkan blok di mana kode Anda memodifikasi variabel instan daripada menyinkronkan metode lengkap untuk meningkatkan kinerja.
Perhatikan bahwa kita perlu mengunci instance servlet karena kita perlu membuat utas instance servlet tertentu aman.
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ThreadSafeServlet extends HttpServlet { @override public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException int counter; { synchronized (this) {
b) Single Thread Model - mengimplementasikan antarmuka SingleThreadModel untuk membuat utas tunggal-utas, yang berarti bahwa hanya satu utas yang akan menjalankan metode layanan () atau doXXX () sekaligus. Servlet single-threaded lebih lambat di bawah beban karena permintaan baru harus menunggu contoh gratis untuk diproses
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ThreadSafeServlet extends HttpServlet implements SingleThreadModel { int counter;
Menggunakan SingleThreadModel sudah usang karena dianjurkan untuk menggunakan blok yang disinkronkan.
4. Kesimpulan
Kita harus sangat berhati-hati ketika menulis servlet, karena "secara default, servlet tidak aman utas"
- Jika servlet Anda tidak memiliki variabel statis atau anggota, Anda tidak perlu khawatir dan servlet Anda aman
- Jika servlet Anda baru saja membaca variabel instan, servlet Anda aman.
- Jika Anda perlu mengubah instance atau variabel statis, perbarui itu dalam blok yang disinkronkan, menjaga instance tetap terkunci
Jika Anda mengikuti aturan di atas dan lain kali seseorang bertanya kepada Anda: "Apakah utas servlet aman?" - jawab dengan percaya diri: "Secara default, tidak, tetapi" servlet saya "aman."
AKHIR
Seperti biasa, kami menunggu pertanyaan, saran, dll. Di sini atau Anda dapat bertanya kepada Sergey Petrelevich pada
pelajaran Terbuka tentang multithreading.