Saat menulis perangkat lunak, Anda sering perlu menggunakan fungsi log cetak, yang dapat membantu Anda men -debug dan memposisikan masalah setelah proyek diluncurkan, itu juga dapat membantu Anda menganalisis data. Tetapi metode asli Java.out.out.println () jarang digunakan dalam pengembangan proyek nyata, dan bahkan alat pemeriksaan kode seperti FindBugs akan berpikir bahwa menggunakan System.out.println () adalah bug.
Mengapa System.out.println (), yang merupakan artefak pemula dari Java, akan ditolak dalam pengembangan proyek nyata? Bahkan, selama Anda menganalisisnya dengan cermat, Anda akan menemukan banyak kerugiannya. Misalnya, jika tidak dikendalikan, semua log akan dicetak seperti biasa setelah proyek diluncurkan, sehingga mengurangi efisiensi operasi; atau tidak dapat merekam log ke file lokal. Anda untuk membedakan kategori mana log ini dicetak.
Pemimpin Anda bukan orang bodoh. Namun, pemimpin Anda cukup bagus, dan itu tidak memungkinkan Anda untuk mencapai alat log niubi dengan berbagai fungsi di awal.
Permintaan ini tidak sulit bagi Anda.
Logutil kelas publik {public final ke dalam debug = 0; System.out.println (msg);}} public void info (string msg) {if (info> = level) {System.out.println (msg);} public void ing msg) {if (error> = level) {System.out.println (msg);}}}
Cetak log melalui kelas ini, dan hanya perlu mengontrol level level untuk mengontrol konten pencetakan secara bebas. Misalnya, proyek sekarang dalam tahap pengembangan, dan level diatur untuk men -debug, sehingga semua informasi log akan dicetak. Jika proyek online, Anda dapat mengatur level ke info, sehingga Anda hanya dapat melihat log dan pencetakan log level di atas. Jika Anda hanya ingin melihat log yang salah, Anda dapat mengatur level ke kesalahan. Dan jika proyek yang Anda kembangkan adalah versi klien, Anda tidak ingin mencetak log apa pun, Anda dapat mengatur level menjadi apa -apa. Anda hanya perlu menelepon saat mencetak:
Logutil baru ().
Anda tidak sabar untuk memperkenalkan alat ini kepada pemimpin Anda.
Tetapi tidak butuh waktu lama bagi pemimpin Anda untuk menemukan Anda memberikan umpan balik. Dia mengatakan bahwa meskipun alat ini mudah digunakan, itu tidak membedakan antara mencetak hal -hal seperti itu. untuk menggunakannya untuk menggunakannya.
Apakah menurut Anda pemimpin Anda sangat masuk akal, dan Anda mencoba memanfaatkan kesempatan ini untuk mempraktikkan mode desain, jadi Anda menulis kode berikut (PS: Kode di sini dilakukan oleh diri saya sendiri, dan saya tidak memperhatikan itu.
Public Logutil {Private Static Logutil Logutilinstance; GetInstance () {if (logutilinstance == null) {logutilinstance = new logutil ();} return logutilinstance;} public void debug (string g. {If (debug> = level) {System.out.println (msg);} } Public void info (string msg) {if (info> = level) {System.out.println (msg);} public void error (string msg) {if (error> = level) {System .out );}} Public static void main (string [] args) {logutil.getInstance ().
Pertama -tama, konstruktor Logutil diprivatisasi, sehingga kata kunci baru tidak dapat digunakan untuk membuat instance logutil. Kemudian gunakan variabel statis slogutil pribadi untuk menyimpan instance, dan berikan metode getinstance publik untuk mendapatkan instance logutil. Slogutil secara langsung. Ini dapat memastikan bahwa hanya akan ada contoh logutil dalam memori. Mode tunggal selesai! Pada saat ini, kode log cetak perlu diubah ke cara berikut:
Logutil.getInstance ().
Anda menunjukkan versi ini kepada pemimpin Anda.
Anda penuh dengan kecurigaan, bukankah mode sampel tunggal diwujudkan seperti ini? Apa yang bisa menjadi bug?
Pemimpin Anda meminta Anda bahwa menggunakan mode single adalah membuat kelas ini hanya memiliki satu contoh dalam memori, tetapi apakah Anda mempertimbangkan situasi pencetakan log dalam multi -utara? Seperti yang ditunjukkan dalam kode berikut:
Public static logutil getInstance () {if (logutilInstance == null) {logutilinstance = new logutil ();} return logutilinstance;}
Jika ada dua utas pada saat yang sama menjalankan metode GetInstance pada saat yang sama, utas pertama hanya mengeksekusi baris kedua dan belum mengeksekusi baris ketiga. Dengan cara ini, mode lajang Anda gagal karena dua contoh yang berbeda dibuat.
Anda tiba -tiba menyadari, tetapi pemikiran Anda sangat cepat, dan Anda segera memikirkan solusinya.
Logutil statis yang disinkronkan publik getInstance () {if (logutilinstance == null) {logutilinstance = new logutil ();} return logutilinstance;}
Dengan cara ini, hanya satu utas yang diizinkan untuk menjalankan kode di GetInstance pada saat yang sama, yang secara efektif memecahkan situasi di mana kedua contoh akan dibuat di atas.
Pemimpin Anda membaca kode baru Anda dan berkata, "Ya, ya. Ini menyelesaikan situasi yang dapat menciptakan dua contoh, tetapi kode ini masih menjadi masalah."
Anda gugup, mengapa ada masalah?
Pemimpin Anda tersenyum: "Jangan gugup, kali ini bukan bug, tetapi dapat dioptimalkan dalam hal kinerja. Lihat, jika Anda menambahkan metode yang disinkronkan ke metode getInstance, maka setiap kali saya pergi ke getInstace Metode, saya akan disinkronkan.
Pertama -tama hapus kata kunci yang disinkronkan dari pernyataan metode, dan tambahkan ke badan metode:
Public static logutil getInstance () {if (logutilInstance == null) {disinkronkan (logutil.class) {if (logutilinstance == null) {// Mungkin diperlukan karena kedua proses tersebut dapat dilampirkan pada saat yang sama pada saat yang sama) waktu pada saat yang sama.
Setelah kode diubah menjadi ini, ia akan memasuki baris ketiga ketika slogutil tidak diinisialisasi, dan kemudian menambahkan kunci sinkron. Segera setelah slogutil diinisialisasi, ia tidak akan lagi pergi ke baris ketiga, sehingga metode getInstance tidak akan dipengaruhi oleh kunci sinkronisasi, dan efisiensi akan ditingkatkan sampai batas tertentu.
Anda tidak dapat membantu tetapi mengagumi metode ini sangat pintar.
Pemimpin Anda segera menjadi rendah hati: "Metode ini disebut penguncian cek ganda, tetapi saya tidak memikirkannya. Anda dapat memeriksa lebih banyak informasi di internet."
Bahkan, saya lebih terbiasa menggunakan mode pria lapar di java
Karakteristik gaya malas adalah pemuatan yang tertunda.
Karakteristik dari gaya Han yang lapar adalah dimuat pada awalnya, sehingga Anda dapat kembali secara langsung ketika Anda menggunakannya (saya sarankan ini lagi, karena tidak perlu mempertimbangkan terlalu banyak masalah keamanan utas. Tentu saja kunci ganda ganda disebutkan untuk menyelesaikan masalah sinkronisasi)
Kode Menerapkan Catatan Log dengan Gaya Hungry Han adalah sebagai berikut:
Logutil Kelas Publik {Private Static Final Logutilinstance = New Logutil (); () {} Public static logutil getInstance () {return logutilinstance;} public void debug (string msg) {if (debug> = level) {system.out.print ln (msg);}} public void info (string msg) {if (info> = level) {System.out.println (msg);}} public void error (string msg) {if (error> = level) {system.out.println (msg);} public atic void main (string [] art) {logutil.getInstance ().