ในการประมวลผลพร้อมกันของเธรด Java มีความสับสนมากมายในการใช้คำหลักระเหยง่าย ฉันคิดว่าการใช้คำหลักนี้สามารถทำให้ทุกอย่างเป็นไปด้วยดีเมื่อใช้การประมวลผลพร้อมกันหลายเธรด
ภาษา Java รองรับมัลติเธรด เพื่อแก้ปัญหาการเกิดขึ้นพร้อมกันของเธรดบล็อกแบบซิงโครนัสและกลไกคำหลักที่ผันผวนได้รับการแนะนำภายในภาษา
ซิงโครไนซ์
ทุกคนคุ้นเคยกับบล็อกที่ซิงโครไนซ์และพวกเขาจะถูกนำไปใช้ผ่านคำหลักที่ซิงโครไนซ์ ด้วยคำสั่งที่ซิงโครไนซ์และบล็อกมีเพียงเธรดเดียวเท่านั้นที่สามารถใช้งานได้ในเวลาเดียวกันเมื่อเข้าถึงมัลติเธรด
วิธีการแก้ไขหรือบล็อกรหัส
ระเหย
สำหรับตัวแปรที่แก้ไขด้วยความผันผวนเธรดจะอ่านค่าที่แก้ไขมากที่สุดของตัวแปรทุกครั้งที่ใช้ตัวแปร ความผันผวนจะถูกนำไปใช้ในทางที่ผิดและใช้สำหรับการดำเนินการอะตอม
มาดูตัวอย่างด้านล่าง เราใช้เคาน์เตอร์ ทุกครั้งที่เธรดเริ่มต้นเมธอด Inc จะถูกเรียกให้เพิ่มหนึ่งรายการลงในตัวนับ
สภาพแวดล้อมการดำเนินการ - JDK เวอร์ชัน: JDK1.6.0_31, หน่วยความจำ: 3G CPU: x86 2.4G
ตัวนับระดับสาธารณะ {นับ int คงที่สาธารณะ = 0; โมฆะคงที่สาธารณะ inc () {// ความล่าช้าที่นี่คือ 1 มิลลิวินาทีทำให้ผลลัพธ์ที่ชัดเจนลอง {thread.sleep (1);} catch (interruptedException e) {} count ++; I <1000;ผลการทำงาน: counter.count = 995
ผลการดำเนินงานจริงอาจแตกต่างกันทุกครั้ง ผลลัพธ์ของเครื่องคือ: การรันผล: counter.count = 995 จะเห็นได้ว่าในสภาพแวดล้อมแบบมัลติเธรดการนับไม่ได้คาดหวังว่าผลลัพธ์จะเป็น 1,000
หลายคนคิดว่านี่เป็นปัญหาพร้อมกันหลายเธรด คุณจะต้องเพิ่มความผันผวนก่อนที่ตัวแปรจะนับเพื่อหลีกเลี่ยงปัญหานี้ จากนั้นเรากำลังแก้ไขรหัสเพื่อดูว่าผลลัพธ์ตรงกับความคาดหวังของเราหรือไม่
เคาน์เตอร์ระดับสาธารณะ {การนับจำนวน int คงที่ของสาธารณะ = 0; โมฆะคงที่สาธารณะ inc () {// ความล่าช้าที่นี่คือ 1 มิลลิวินาทีทำให้ผลลัพธ์ที่ชัดเจนลอง {เธรด. sleep (1);} catch (interruptedException e) {} count ++; = 0; i <1000;ผลการทำงาน: counter.count = 992
ผลการดำเนินการยังไม่ถึง 1,000 เท่าที่เราคาดไว้ มาวิเคราะห์เหตุผลด้านล่าง
ในบทความคอลเลกชัน Java Garbage การจัดสรรหน่วยความจำในขณะที่ JVM อธิบายไว้ หนึ่งในพื้นที่หน่วยความจำคือสแต็กเครื่องเสมือน JVM และแต่ละเธรดมีสแต็กเธรดเมื่อทำงาน
สแต็กเธรดจะบันทึกข้อมูลค่าตัวแปรระหว่างรันไทม์เธรด เมื่อเธรดเข้าถึงค่าของวัตถุที่แน่นอนก่อนอื่นให้ค้นหาค่าของตัวแปรที่สอดคล้องกับหน่วยความจำ HEAP ผ่านการอ้างอิงของวัตถุจากนั้นใส่หน่วยความจำฮีป
ค่าเฉพาะของตัวแปรถูกโหลดลงในหน่วยความจำท้องถิ่นของเธรดและสำเนาของตัวแปรถูกสร้างขึ้น หลังจากนั้นเธรดจะไม่มีความสัมพันธ์ใด ๆ กับค่าตัวแปรของวัตถุในหน่วยความจำ HEAP อีกต่อไป แต่จะแก้ไขค่าของตัวแปรคัดลอกโดยตรง
ในช่วงเวลาหนึ่งหลังจากการแก้ไข (ก่อนที่เธรดจะออก) ค่าของการคัดลอกตัวแปรเธรดจะถูกเขียนโดยอัตโนมัติกลับไปยังตัวแปรวัตถุในฮีป วิธีนี้ค่าของวัตถุในกองจะเปลี่ยน ภาพต่อไปนี้
อ่านและโหลดตัวแปรคัดลอกจากหน่วยความจำหลักไปยังหน่วยความจำการทำงานปัจจุบัน
ใช้และกำหนดรหัสดำเนินการเพื่อเปลี่ยนค่าตัวแปรที่ใช้ร่วมกัน
จัดเก็บและเขียนเนื้อหาที่เกี่ยวข้องกับหน่วยความจำหลักรีเฟรชพร้อมข้อมูลหน่วยความจำที่ใช้งานได้
การใช้งานและการกำหนดสามารถปรากฏได้หลายครั้ง
อย่างไรก็ตามการดำเนินการเหล่านี้ไม่ใช่อะตอมนั่นคือหลังจากโหลดการอ่านหากตัวแปรนับหน่วยความจำหลักถูกแก้ไขค่าในหน่วยความจำการทำงานของเธรดจะไม่ทำให้เกิดการเปลี่ยนแปลงที่สอดคล้องกันเนื่องจากมีการโหลดดังนั้นผลลัพธ์ที่คำนวณจะแตกต่างจากที่คาดไว้
สำหรับตัวแปรที่แก้ไขโดยความผันผวนเครื่องเสมือน JVM จะมั่นใจได้ว่าค่าที่โหลดจากหน่วยความจำหลักไปยังหน่วยความจำการทำงานของเธรดเป็นล่าสุด
ตัวอย่างเช่นหากเธรด 1 และเธรด 2 กำลังดำเนินการอ่านและโหลดและพบว่าค่าการนับในหน่วยความจำหลักคือ 5 ค่าล่าสุดจะถูกโหลด
หลังจากการนับจำนวนฮีปถูกแก้ไขในเธรด 1 มันจะถูกเขียนลงในหน่วยความจำหลักและตัวแปรนับในหน่วยความจำหลักจะกลายเป็น 6
เนื่องจากเธรด 2 ได้ดำเนินการอ่านและโหลดแล้วค่าตัวแปรของจำนวนหน่วยความจำหลักจะได้รับการปรับปรุงเป็น 6 หลังจากการดำเนินการ
สิ่งนี้ทำให้เกิดขึ้นพร้อมกันหลังจากสองเธรดได้รับการแก้ไขด้วยคำหลักที่ผันผวนในเวลา
ข้างต้นคือความหมายของคำหลักที่ผันผวนใน Java ที่แนะนำโดยบรรณาธิการ ฉันหวังว่ามันจะเป็นประโยชน์กับคุณ หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับคุณทันเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!