1. Apa itu pola desain
Dalam rekayasa perangkat lunak, pola desain adalah solusi yang diusulkan untuk berbagai masalah umum (berulang) dalam desain perangkat lunak. Istilah ini diperkenalkan ke dalam ilmu komputer dari bidang desain arsitektur pada 1990 -an oleh Erich Gamma dan lainnya.
Geng 4 Orang Terkenal: Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (GOF)
Pola Desain: Dasar-dasar perangkat lunak berorientasi objek yang dapat digunakan kembali
2. Singleton Mode
Kelas objek singleton harus dijamin hanya memiliki satu contoh. Sering kali seluruh sistem hanya perlu memiliki satu objek global, yang kondusif untuk koordinasi kami terhadap perilaku keseluruhan sistem.
Misalnya: Konfigurasi Informasi Global
Implementasi paling sederhana dari mode singleton:
kelas publik singleton {private singleton () {system.out.println ("singleton is create"); } private static singleton instance = singleton baru (); public static singleton getInstance () {return instance; }} Keunikan ditentukan oleh konstruktor pribadi dan statis.
Kekurangan: Saat instance dihasilkan sulit dikendalikan
Meskipun kita tahu bahwa ketika singleton kelas pertama kali dimuat, sebuah instance dihasilkan.
Tetapi jika ada properti lain di kelas ini
kelas publik singleton {status int statis publik = 1; singleton pribadi () {System.out.println ("Singleton is Create"); } private static singleton instance = singleton baru (); public static singleton getInstance () {return instance; }} Saat menggunakan
System.out.println (singleton.status);
Contoh ini diproduksi. Mungkin Anda tidak ingin contoh ini dihasilkan saat ini.
Jika sistem memberikan perhatian khusus pada masalah ini, metode implementasi singleton ini tidak terlalu bagus.
Solusi untuk mode singleton kedua:
kelas publik singleton {private singleton () {system.out.println ("singleton is create"); } private static singleton instance = null; public static sinkronisasi singleton getInstance () {if (instance == null) instance = new singleton (); instance return; }} Biarkan instance dibuat hanya ketika metode getInstance () dipanggil, dan keamanan utas dipastikan melalui disinkronkan.
Ini mengontrol saat instance dibuat.
Pendekatan ini khas pemuatan malas.
Tetapi satu masalah adalah bahwa kinerja akan berdampak dalam skenario konkurensi yang tinggi. Meskipun dikembalikan dengan hanya satu penilaian, ia akan berdampak dalam kasus konkurensi tinggi, ia akan memiliki dampak yang lebih atau kurang karena Anda harus mendapatkan kunci yang disinkronkan.
Agar efisien, ada metode ketiga:
Public Class Staticsingleton {private staticsingleton () {System.out.println ("Staticsingleton is create"); } private static class singletonHolder {private static staticsingleton instance = new staticsingleton (); } public static staticsingleton getInstance () {return singletonHolder.instance; }} Karena ketika kelas dimuat, kelas dalamnya tidak akan dimuat. Ini memastikan bahwa instance akan dihasilkan hanya ketika getInstance () dipanggil, waktu menghasilkan instance dikendalikan, dan pemuatan yang tertunda tercapai.
Dan disinkronkan dihapus untuk membuat kinerja lebih baik dan statis digunakan untuk memastikan keunikan.
3. Mode invarian
Setelah keadaan internal suatu kelas dibuat, itu tidak akan berubah selama periode seumur hidup.
Mode unchange tidak memerlukan sinkronisasi
Buat kelas yang tidak berubah:
Produk kelas akhir publik {// Pastikan tidak ada string final pribadi subkelas no; // atribut pribadi tidak akan diperoleh oleh objek lain nama string final pribadi; // jaminan akhir bahwa atribut tidak akan ditetapkan dua kali harga ganda pribadi; Produk Publik (String No, String Name, Double Price) {// Saat membuat objek, data harus ditentukan super (); // Karena setelah pembuatan, itu tidak dapat dimodifikasi ini.no = tidak; this.name = name; this.price = harga; } public string getNo () {return no; } public string getName () {return name; } public double getPrice () {harga kembali; }} Kasus pola yang tidak berubah di java meliputi:
java.lang.string
java.lang.Boolean
java.lang.byte
java.lang.character
java.lang.double
java.lang.float
java.lang.integer
java.lang.long
java.lang.short
4. Mode Masa Depan
Gagasan intinya adalah panggilan asinkron
Non-sinkron:
Asynchronous:
Call_return pertama dikembalikan karena tugas belum selesai.
Tetapi pengembalian ini mirip dengan pesanan dalam belanja, dan Anda bisa mendapatkan hasil berdasarkan pesanan ini di masa depan.
Jadi model masa depan ini berarti bahwa "masa depan" dapat diperoleh, yang berarti bahwa perintah atau kontrak adalah "janji" dan akan memberikan hasil di masa depan.
Implementasi Sederhana Mode Masa Depan:
Apa yang didapat penelepon adalah data, yang mungkin menjadi futuredata pada awalnya, karena RealData lambat dibangun. Pada suatu waktu di masa depan, RealData dapat diperoleh melalui Futuredata.
Implementasi Kode:
data antarmuka publik {string publik getResult (); } Public Class Futuredata mengimplementasikan data {realData realData = null; // Futuredata adalah pembungkus realdata yang dilindungi boolean isready = false; public disinkronkan void setRealData (realData realData) {if (isready) {return; } this.realdata = realData; isready = true; notifyall (); // RealData telah disuntikkan, beri tahu getResult ()} string sinkronisasi publik getResult () // akan menunggu konstruksi realData untuk menyelesaikan {while (! Isready) {coba {tunggu (); // tunggu sepanjang waktu untuk mengetahui bahwa realData disuntikkan} catch (interruptedException e) {}} return realData.Result; // diimplementasikan oleh realData}} kelas publik RealData mengimplementasikan data {hasil string akhir yang dilindungi; Public RealData (String ParA) {// Konstruksi RealData mungkin sangat lambat dan mengharuskan pengguna untuk menunggu lama. Di sini kita menggunakan tidur untuk mensimulasikan StringBuffer SB = New StringBuffer (); untuk (int i = 0; i <10; i ++) {SB.Append (para); Coba {// Gunakan tidur di sini, bukan utas operasi yang sangat lambat.sleep (100); } catch (InterruptedException e) {}} result = sb.toString (); } public string getResult () {return hasil; }} klien kelas publik {permintaan data publik (final string querystr) {final futuredata future = new futuredata (); utas baru () {public void run () {// realdata sangat lambat untuk dibangun, // jadi realdata di utas terpisah realData = new realData (querystr); Future.setrealData (RealData); } } }.awal(); kembali masa depan; // futuredata akan segera dikembalikan}} public static void main (string [] args) {client client = new client (); // Ini akan segera dikembalikan karena apa yang Anda dapatkan adalah futuredata alih -alih data realData data = client.Request ("name"); System.out.println ("Permintaan Selesai"); Coba {// Di sini Anda dapat menggunakan tidur alih -alih memproses logika bisnis lainnya // dalam proses memproses logika bisnis ini, RealData dibuat, memanfaatkan sepenuhnya waktu tunggu. Sleep (2000); } catch (InterruptedException e) {} // Gunakan sistem data nyata.out.println ("data =" + data.getResult ()); }Ada juga banyak dukungan mode masa depan di JDK:
Selanjutnya, gunakan kelas dan metode yang disediakan oleh JDK untuk mengimplementasikan kode sekarang:
Impor java.util.concurrent.callable; Public Class RealData mengimplementasikan Callable <string> {Private String PARA; realData publik (string para) {this.para = para; } @Override public string call () melempar Exception {StringBuffer SB = New StringBuffer (); untuk (int i = 0; i <10; i ++) {SB.Append (para); coba {thread.sleep (100); } catch (InterruptedException e) {}} return sb.toString (); }} Impor java.util.concurrent.executionException; impor java.util.concurrent.executorservice; impor java.util.concurrent.executors; impor java.util.concurrent.futuretask; class class futuremain {public static void main (string] {string] {string] {string] {string {string) public conscepion {public static void {string) Futuretask Futuretask <string> Future = New FutureTask <string> (realData baru ("A")); ExecutorService Executor = Executors.newfixedThreadPool (1); // Jalankan FutureTask, setara dengan Client.Request ("A") dalam contoh di atas Kirim permintaan // Aktifkan utas di sini untuk melakukan realData call () dan mengeksekusi executor.submit (masa depan); System.out.println ("Permintaan Selesai"); Coba {// Operasi data tambahan masih dapat dilakukan di sini, dan tidur dapat digunakan alih -alih memproses thread logika bisnis lainnya.sleep (2000); } catch (InterruptedException e) {} // setara dengan data.getResult (), dapatkan nilai pengembalian metode panggilan () // jika metode call () tidak dieksekusi pada saat ini, ia masih akan menunggu system.out.println ("data =" + Future.get ()); }} Yang perlu Anda perhatikan di sini adalah bahwa FutureTask adalah kelas yang memiliki fungsi di masa depan dan fungsi yang dapat dijalankan. Jadi bisa berjalan lagi, dan akhirnya mendapatkannya.
Tentu saja, jika data sebenarnya tidak siap saat menelepon Future.get (), itu masih akan menyebabkan situasi pemblokiran sampai data siap.
Tentu saja ada cara yang lebih mudah:
impor java.util.concurrent.executionException; impor java.util.concurrent.executorservice; impor java.util.concurrent.executors; impor java.util.concurrent.future; class public futureMain2 {public static void main (string [] argropscepteCceptEcceptePicion, publiccepteCCEPION, PUBLIC STATIC VOID MAIN (STRING [] Executors.newfixedThreadPool (1); // Jalankan FutureTask, setara dengan Client.Request ("A") dalam contoh di atas Kirim permintaan // buka utas di sini untuk melakukan realData call () dan jalankan Future <string> Future = executor.submit (realData baru ("a")); System.out.println ("Permintaan Selesai"); Coba {// Operasi data tambahan masih dapat dilakukan di sini, gunakan tidur alih -alih utas pemrosesan logika bisnis lainnya. Sleep (2000); } catch (InterruptedException e) {} // setara dengan data.getResult (), dapatkan nilai pengembalian metode panggilan () // Jika metode call () tidak dijalankan pada saat ini, System.out.println masih akan menunggu System.out.println ("Data =" + Found.get ()); }} Karena Callable memiliki nilai pengembalian, Anda dapat secara langsung mengembalikan objek di masa depan.
5. Produsen dan Konsumen
Model produser-konsumen adalah model desain multi-threaded klasik. Ini memberikan solusi yang baik untuk kolaborasi antara banyak utas. Dalam model produser-konsumen, biasanya ada dua jenis utas, yaitu beberapa utas produsen dan beberapa utas konsumen. Utas produser bertanggung jawab untuk mengirimkan permintaan pengguna, sementara utas konsumen bertanggung jawab untuk menangani tugas yang dikirimkan secara khusus oleh produsen. Produser dan konsumen berkomunikasi melalui buffer memori bersama.
Saya telah menulis sebuah artikel di masa lalu untuk mengimplementasikan berbagai metode menggunakan Java untuk mengimplementasikan produsen dan konsumen, jadi saya tidak akan menjelaskannya di sini.