บทความนี้วิเคราะห์การใช้งานระเหยและซิงโครไนซ์ใน Java multi-threading พร้อมตัวอย่าง แบ่งปันกับทุกคนสำหรับการอ้างอิงของคุณ วิธีการดำเนินการเฉพาะมีดังนี้:
คัดลอกรหัสดังต่อไปนี้: แพคเกจ com.chzhao;
Volatiletest ระดับสาธารณะขยายเธรด {
จำนวน int คงที่ส่วนตัว = 0;
โมฆะสาธารณะวิ่ง () {
นับ++;
-
โมฆะคงที่สาธารณะ main (String [] args) {
เธรดเธรด[] = เธรดใหม่[10000];
สำหรับ (int i = 0; i < threads.length; i++) {
เธรด [i] = การทดสอบระเหยใหม่ ();
-
สำหรับ (int i = 0; i < threads.length; i++) {
กระทู้[i].เริ่มต้น();
-
พยายาม {
เธรด.สลีป(1,000);
} จับ (InterruptedException e) {
e.printStackTrace();
-
System.out.println (นับ);
-
-
รหัสเป็นไปตามข้างต้น ผลลัพธ์ที่คาดหวังคือ 10,000 อย่างไรก็ตาม เนื่องจาก count++ ไม่ปลอดภัยสำหรับเธรด ผลลัพธ์จึงมักจะน้อยกว่า 10,000
เพื่อแก้ไขปัญหานี้ จึงได้เพิ่มคำสำคัญที่เปลี่ยนแปลงได้
คัดลอกรหัสดังต่อไปนี้: แพคเกจ com.chzhao;
Volatiletest ระดับสาธารณะขยายเธรด {
จำนวน int คงที่แบบระเหยส่วนตัว = 0;
โมฆะสาธารณะวิ่ง () {
นับ++;
-
โมฆะคงที่สาธารณะ main (String [] args) {
เธรดเธรด[] = เธรดใหม่[10000];
สำหรับ (int i = 0; i < threads.length; i++) {
เธรด [i] = การทดสอบระเหยใหม่ ();
-
สำหรับ (int i = 0; i < threads.length; i++) {
กระทู้[i].เริ่มต้น();
-
พยายาม {
Thread.sleep (2000);
} จับ (InterruptedException e) {
e.printStackTrace();
-
System.out.println (นับ);
-
-
หลังจากแก้ไขแล้ว มักจะส่งออกค่าอื่นที่ไม่ใช่ 10,000
แก้ไขให้เป็นรูปแบบซิงโครไนซ์ รหัสจะเป็นดังนี้:
คัดลอกโค้ดดังนี้: package com.chzhao;
SynchronizedTest คลาสสาธารณะขยายเธรด {
จำนวน int คงที่ส่วนตัว = 0;
โมฆะสาธารณะวิ่ง () {
ซิงโครไนซ์ (LockClass.lock) {
นับ++;
-
-
โมฆะคงที่สาธารณะ main (String [] args) {
เธรดเธรด[] = เธรดใหม่[10000];
สำหรับ (int i = 0; i < threads.length; i++) {
เธรด [i] = SynchronizedTest ใหม่ ();
-
สำหรับ (int i = 0; i < threads.length; i++) {
กระทู้[i].เริ่มต้น();
-
พยายาม {
Thread.sleep (2000);
} จับ (InterruptedException e) {
e.printStackTrace();
-
System.out.println (นับ);
-
-
คัดลอกรหัสดังต่อไปนี้: แพคเกจ com.chzhao;
LockClass คลาสสาธารณะ {
ไบต์สาธารณะแบบคงที่ [] ล็อค = ไบต์ใหม่ [0];
-
หลังจากการปรับเปลี่ยนนี้ ผลลัพธ์จะเป็น 10,000
นี่หมายความว่าคำสำคัญที่ผันผวนนั้นไร้ประโยชน์โดยสิ้นเชิงใช่หรือไม่ การซิงโครไนซ์เท่านั้นที่สามารถรับประกันความปลอดภัยของเธรดได้หรือไม่
แสดงให้เห็น:
ภาษา Java มีกลไกการซิงโครไนซ์โดยธรรมชาติสองกลไก: บล็อกที่ซิงโครไนซ์ (หรือวิธีการ) และตัวแปรระเหย มีการเสนอกลไกทั้งสองเพื่อให้บรรลุความปลอดภัยของเธรดโค้ด ตัวแปรระเหยมีการซิงโครไนซ์น้อยกว่า (แต่บางครั้งก็ง่ายกว่าและถูกกว่า) และการใช้งานก็มีแนวโน้มที่จะเกิดข้อผิดพลาดมากกว่าเช่นกัน ตัวแปรระเหยในภาษา Java อาจถูกมองว่า "ซิงโครไนซ์น้อยกว่า" เมื่อเปรียบเทียบกับบล็อกที่ซิงโครไนซ์ ตัวแปรระเหยต้องการการเข้ารหัสน้อยกว่าและมีค่าใช้จ่ายรันไทม์น้อยกว่า แต่สามารถบรรลุฟังก์ชันการทำงานได้เป็นเพียงส่วนหนึ่งของการซิงโครไนซ์
กล่าวอีกนัยหนึ่ง ในบางกรณี volitile จะสะดวกในการใช้งานมากกว่าการซิงโครไนซ์ แต่แน่นอนว่าการซิงโครไนซ์นั้นแย่กว่า
ฉันหวังว่าบทความนี้จะเป็นประโยชน์กับการเขียนโปรแกรม Java ของทุกคน