Penyusunan semula arahan akan membantu meningkatkan kecekapan pelaksanaan program dalam persekitaran satu utas dan tidak akan memberi kesan negatif kepada program dalam persekitaran berbilang benang, penyusunan semula arahan akan membawa maksud kepada program yang tidak dijangka.
Berikut ialah contoh yang boleh memulihkan penyusunan semula arahan 100%. Kaedah
public class D { static Integer a; static Boolean flag; public static void writer() { a = 1; flag = true; } public static void reader() { if (flag != null && flag) { System.out.println(a); a = 0; flag = false; } } }
reader
hanya mencetak nilai pembolehubah flag
ke konsol apabila pembolehubah a
adalah benar. Kaedah
writer
mula-mula melaksanakan operasi penetapan pembolehubah a
, dan kemudian melaksanakan operasi penetapan pembolehubah flag
.
Jika anda mengikut logik analisis di atas, maka hasil yang dicetak oleh konsol mestilah semuanya 1.
Jika kod tidak mempunyai penyusunan semula arahan, maka apabila pembolehubah flag
adalah benar, pembolehubah a
mestilah 1.
Dalam kod di atas, terdapat penyusunan semula arahan dalam kedua-dua kelas kaedah berkenaan pembolehubah a
dan pembolehubah flag
.
public static void writer() { a = 1; flag = true; }
Dengan memerhati keluaran log, kami mendapati terdapat sejumlah besar 0 keluaran.
Apabila penyusunan semula arahan berlaku di dalam kaedah writer
, pembolehubah flag
ditetapkan dahulu Pada masa ini, jika utas semasa terganggu dan utas lain memanggil kaedah reader
, ia adalah. mengesan bahawa pembolehubah flag
adalah benar, maka nilai pembolehubah a
akan dicetak. Pada masa ini, terdapat hasil dalam konsol yang melebihi nilai yang dijangkakan.
Apabila menggunakan kata kunci baharu untuk mencipta objek, terdapat penyusunan semula arahan kerana operasi bukan atomnya penyusunan semula Arahan akan membawa kesan negatif dalam berbilang -persekitaran berulir.
public class Singleton { private static UserModel instance; public static UserModel getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new UserModel(2, "B"); } } } return instance; } } @Data @AllArgsConstructor class UserModel { private Integer userId; private String userName; }
Gunakan kata kunci baharu untuk mencipta objek, yang dibahagikan secara kasar kepada proses berikut:
Buat alamat rujukan dalam ruang tindanan
Gunakan fail kelas sebagai templat untuk memperuntukkan memori dalam objek ruang timbunan
Memulakan pembolehubah ahli
Gunakan pembina untuk memulakan
Tetapkan nilai rujukan kepada pembolehubah storan kiri
Untuk contoh di atas, anggapkan bahawa utas pertama memasuki blok kod yang disegerakkan dan mula mencipta objek Disebabkan wujudnya penyusunan semula, penciptaan objek biasa proses terganggu, yang mungkin berlaku selepas alamat rujukan dibuat dalam ruang tindanan , tetapkan nilai rujukan kepada pembolehubah storan kiri, dan kemudian gangguan berlaku disebabkan oleh kehabisan kepingan masa penjadualan CPU.
Apabila urutan berikutnya mengesan bahawa pembolehubah instance
tidak kosong, ia akan digunakan secara langsung. Oleh kerana objek tunggal tidak dibuat seketika, menggunakannya secara langsung akan membawa hasil yang tidak dijangka.
Gunakan kelas atom untuk merangkum satu set pembolehubah yang berkaitan ke dalam objek, mengambil kesempatan daripada ciri-ciri operasi atom, dengan berkesan mengelakkan masalah penyusunan semula arahan.
@Data @NoArgsConstructor @AllArgsConstructor public class ValueModel { private Integer value; private Boolean flag; }
Kelas atom harus menjadi penyelesaian pilihan untuk menyusun semula arahan dalam persekitaran berbilang benang bukan sahaja mudah difahami, tetapi kunci mutex bukan berat yang digunakan antara benang adalah agak cekap.
public class E { private static final AtomicReference<ValueModel> ar = new AtomicReference<>(new ValueModel()); public static void writer() { ar.set(new ValueModel(1, true)); } public static void reader() { ValueModel valueModel = ar.get(); if (valueModel.getFlag() != null && valueModel.getFlag()) { System.out.println(valueModel.getValue()); ar.set(new ValueModel(0, false)); } } }
Apabila arahan disusun semula untuk sekumpulan pembolehubah yang berkaitan, menggunakan kelas operasi atom ialah penyelesaian yang lebih baik.
public class Singleton { private volatile static UserModel instance; public static UserModel getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new UserModel(2, "B"); } } } return instance; } } @Data @AllArgsConstructor class UserModel { private Integer userId; private String userName; }
2. Penyusunan semula arahan dalam persekitaran berbilang benang
Walaupun kunci yang disegerakkan boleh mengelakkan kesan buruk penyusunan semula dalam persekitaran berbilang benang, overhed benang yang disebabkan oleh kunci mutex adalah agak besar dan tidak disyorkan.
Operasi bukan atom dalam blok yang disegerakkan masih boleh menyebabkan penyusunan semula arahanAtas ialah kandungan terperinci Bagaimana untuk menyelesaikan penyusunan semula arahan Java dalam persekitaran berbilang benang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!