Unsafe เป็นรากฐานที่สำคัญของการดำเนินการที่ปราศจากการล็อค Java และเป็นสิ่งที่ขาดไม่ได้ในชั้นเรียนพร้อมกันที่ไม่มีล็อค ตัวอย่างเช่น ConcurrentHashMap และ ConcurrentLinkedQueue ทั้งหมดถูกนำมาใช้โดยคลาสที่ไม่ปลอดภัย เมื่อเทียบกับล็อคในชวาโดยทั่วไปไม่มีค่าใช้จ่ายและจะรอ บทความนี้ส่วนใหญ่แนะนำการดำเนินงานหลักใน Unsafe
1 เปรียบเทียบและ swap
/*** เปรียบเทียบค่าในตำแหน่งหน่วยความจำที่ออฟเซ็ตของ OBJ และค่าที่คาดหวังและอัปเดตหากเหมือนกัน การอัปเดตนี้ไม่สามารถขัดจังหวะได้ ** @param obj วัตถุที่ต้องได้รับการอัปเดต* @param ชดเชยการชดเชยของฟิลด์จำนวนเต็มใน obj* @param คาดว่าค่าที่คาดหวังในฟิลด์* @param อัพเดตหากค่าที่คาดหวังคาดว่าจะเหมือนกับค่าปัจจุบันของฟิลด์ อัปเดต);
นี่คือการดำเนินการ CAS ที่มีชื่อเสียงซึ่งแบ่งออกเป็นสามขั้นตอน
ตระกูล CAS ยังรวมถึงการเปรียบเทียบและ swapObject (), เปรียบเทียบและแอปพลิเคชัน (), (), (), (), (), ()
ใช้ตัวอย่างคลาสสิกจาก Atomicinteger เพื่อแสดง:
Public Final int getandadd (int delta) {return unsafe.getandaddint (นี่, valueOffset, delta);} // unsafe.getandaddintpublic final int getandaddint (Object var1, Long Var2, int var4) {int var5; ทำ { / ** รับค่าดั้งเดิม* / var5 = this.getIntVolatile (var1, var2); / ** ยืนยันว่าค่าดั้งเดิมไม่ได้รับการแก้ไขโดยเธรดอื่นจากนั้นดำเนินการอัปเดต VAR5 + VAR4 การดำเนินการ*/} ในขณะที่ (! this.Compareandswapint (var1, var2, var5, var5 + var4)); ส่งคืน var5;}2 putorder
/**** ตั้งค่าค่าของฟิลด์จำนวนเต็มที่ออฟเซ็ตที่ระบุในวัตถุที่ให้มาเป็นค่าที่กำหนด นี่คือเวอร์ชันที่สั่งซื้อหรือขี้เกียจ * ของ <code> putintvolatile (วัตถุ, ยาว, int) </code> ซึ่ง * ไม่รับประกันการมองเห็นทันทีของการเปลี่ยนแปลงไปยังเธรด * อื่น ๆ มันมีประโยชน์จริงๆที่ฟิลด์จำนวนเต็มคือ * <code> ผันผวน </code> และคาดว่าจะเปลี่ยนแปลงโดยไม่คาดคิด * * @param obj วัตถุที่มีฟิลด์เพื่อแก้ไข * @param ชดเชยการชดเชยของฟิลด์จำนวนเต็มภายใน <code> obj </code> * @param ค่าค่าใหม่ของฟิลด์ * @See #PutIntVolatile (Object, Long, Int) */ Void PutorderedInt (Object OBJ, Offset ยาว, ค่า int);
ปรับเปลี่ยนตำแหน่งที่ออฟเซ็ตของวัตถุ OBJ ถูกชดเชยให้เป็นค่าเนื่องจากไม่มีการทำงานของหน่วยความจำใน Java และการดำเนินการของ UNSAFE นี้เพียงแค่เสริมการทำงานของหน่วยความจำไม่เพียงพอ นอกจากนี้ยังสามารถใช้สำหรับการดำเนินการอาร์เรย์เช่นพร้อมกัน
เซ็กเมนต์ <k, v> s0 = เซ็กเมนต์ใหม่ <k, v> (loadfactor, (int) (cap * loadfactor), (hashentry <k, v> []) ใหม่ hashentry [cap]); เซ็กเมนต์ <k, v> [] ss = (เซ็กเมนต์ <k, v> []) เซ็กเมนต์ใหม่ [ssize]; // เขียน S0 ไปยังตำแหน่งที่อาร์เรย์ถูกแยกเป็น 0: SS [0] = S0 unSafe.putOrderEdObject (SS, SBASE, S0); // สั่งเขียนส่วน [0]
ควรสังเกตว่า OBJ จำเป็นต้องตั้งค่าให้มีความผันผวนมิฉะนั้นจะมองไม่เห็นกับเธรดอื่น ๆ
3 putxxxvolatile
/**** ตั้งค่าค่าของฟิลด์จำนวนเต็มที่ออฟเซ็ตที่ระบุในวัตถุ* ที่ให้ไว้กับค่าที่กำหนดด้วยความหมายของร้านค้าผันผวน * * @param obj วัตถุที่มีฟิลด์เพื่อแก้ไข * @param ชดเชยการชดเชยของฟิลด์จำนวนเต็มภายใน <code> obj </code> * @param ค่าค่าใหม่ของฟิลด์ */ โมฆะประชาชน Putintvolatile (Object OBJ, ชดเชยยาว, ค่า int);
มันให้ความรู้สึกเหมือนกับ PutorderInt เพราะจะต้องตั้งค่าให้มีความผันผวนมิฉะนั้นการใช้งานคืออะไร?
ข้างต้นคือคะแนนความรู้ทั้งหมดที่ฉันแบ่งปันกับคุณในครั้งนี้ ขอบคุณสำหรับการสนับสนุน Wulin.com