Dalam Mode Singleton Implementasi Java kemarin, mekanisme kunci pemeriksaan ganda kami memperkenalkan kata kunci volatile karena masalah pemesanan ulang instruksi. Banyak teman bertanya kepada saya, mengapa saya perlu menambahkan kata kunci volatile ? Dan efek ajaib apa yang dimilikinya?
Mengenai kata kunci volatile , kami secara singkat menyebutkan dalam Penjelasan Kemarin: Variabel bersama yang dimodifikasi oleh volatile akan memiliki dua atribut berikut:
Variabel bersama: Jika suatu variabel memiliki salinan di memori kerja beberapa utas, maka variabel ini adalah variabel bersama dari utas ini.
Visibilitas: Modifikasi utas ke nilai variabel bersama dapat dilihat oleh utas lain secara tepat waktu.
Untuk pemesanan ulang, jika Anda tidak terbiasa dengan itu, cukup google itu, jadi saya tidak akan menyebutkannya di sini. Ingatlah bahwa ketika mengoperasikan variabel bersama di beberapa utas, Anda harus ingat untuk menambahkan modifikasi yang mudah menguap.
Karena keterbatasan waktu, kita masih harus sampai ke topik hari ini terlebih dahulu. Kata kunci yang mudah menguap masih mudah dideteksi dalam wawancara yang membutuhkan keterampilan pemrograman bersamaan. Saya akan menjelaskannya secara singkat kepada Anda nanti.
Masukkan simpul kepala dari satu daftar tertaut dan cetak nilai setiap node dari ujung ke ujung.
Kami memiliki banyak daftar tertaut, daftar tertaut tunggal, daftar tertaut dua arah, daftar tertaut cincin, dll. Ini adalah mode daftar terkait tunggal yang paling umum. Kami biasanya menyimpan data di area penyimpanan data, dan kemudian pointer menunjuk ke simpul berikutnya. Meskipun tidak ada konsep pointer di Java, referensi Java sesuai dengan masalah.
Ketika kita melihat pertanyaan ini, kita sering dengan cepat menyadari bahwa setiap node memiliki atribut berikutnya, jadi sangat mudah untuk output dari awal hingga akhir. Jadi kita secara alami akan berpikir terlebih dahulu menggunakan loop sementara untuk mengeluarkan semua node dan menyimpannya di array, dan kemudian melintasi array dalam urutan terbalik, sehingga nilai simpul dari satu daftar tertaut dapat dicetak dalam urutan terbalik.
Kami berasumsi bahwa data node adalah tipe int. Kode implementasi adalah sebagai berikut:
public class test05 {public static class node {int data; Node selanjutnya; } public static void printLinkReverse (node head) {arrayList <node> node = new ArrayList <> (); while (head! = null) {nodes.add (head); head = head.next; } untuk (int i = node.size ()-1; i> = 0; i--) {System.out.print (node.get (i) .data + ""); }} public static void main (string [] args) {node head = new node (); head.data = 1; head.next = node new (); head.next.data = 2; head.next.next = new node (); head.next.next.data = 3; head.next.next.next.next = new node (); head.next.next.next.data = 4; head.next.next.next.next.next = new node (); head.next.next.next.data = 5; printlinkreverse (kepala); }}Metode ini memang dapat mengimplementasikan pencetakan orde balik dari data daftar tertaut, tetapi jelas menggunakan dua siklus penuh, dengan kompleksitas waktu O (n²). dll! Output terbalik? Tampaknya ada struktur data yang dapat menyelesaikan masalah ini dengan sempurna, dan struktur data ini adalah tumpukan.
Tumpukan adalah struktur data "terakhir dalam keluar pertama". Prinsip tumpukan dapat lebih memenuhi persyaratan kami, sehingga kode implementasinya adalah sebagai berikut:
public class test05 {public static class node {int data; Node selanjutnya; } public static void printLinkReverse (node head) {stack <node> stack = new stack <> (); while (head! = null) {stack.push (head); head = head.next; } while (! stack.isempty ()) {System.out.print (stack.pop (). Data + ""); }} public static void main (string [] args) {node head = new node (); head.data = 1; head.next = node new (); head.next.data = 2; head.next.next = new node (); head.next.next.data = 3; head.next.next.next.next = new node (); head.next.next.next.data = 4; head.next.next.next.next.next = new node (); head.next.next.next.next.data = 5; printlinkreverse (kepala); }}Karena dapat diimplementasikan menggunakan tumpukan, sangat mudah bagi kita untuk berpikir bahwa rekursi juga dapat menyelesaikan masalah ini, karena rekursi pada dasarnya adalah struktur tumpukan. Untuk mengimplementasikan daftar tautan output pesanan terbalik, setiap kali kami mengakses node, pertama -tama kami secara rekursif mengeluarkan simpul di belakangnya, dan kemudian mengeluarkan node itu sendiri. Dengan cara ini, hasil output dari daftar tertaut secara alami akan dibalik.
Kodenya adalah sebagai berikut:
public class test05 {public static class node {int data; Node selanjutnya; } public static void printLinkReverse (node head) {if (head! = null) {printLinkReverse (head.next); System.out.print (head.data+""); }} public static void main (string [] args) {node head = new node (); head.data = 1; head.next = node new (); head.next.data = 2; head.next.next = new node (); head.next.next.data = 3; head.next.next.next = new node (); head.next.next.next.data = 4; head.next.next.next.next.next.next = new node (); head.next.next.next.next.data = 5; printlinkreverse (kepala); }} Meskipun kode rekursif memang terlihat sangat rapi, ada masalah: ketika daftar yang ditautkan sangat panjang, itu pasti akan mengarah pada tingkat panggilan fungsi yang dalam, yang dapat menyebabkan fungsi tumpukan panggilan overflow. Oleh karena itu, kode yang menampilkan kode berdasarkan loop lebih kuat.
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.