การวิจัยหลักในบทความนี้คือเนื้อหาที่เกี่ยวข้องของการใช้งานของ ConcurrentMap.putIfAbsent(key,value) ดังต่อไปนี้
สถานการณ์ประเภทนี้มักจะพบในธุรกิจ MAP พร้อมกันพร้อมกันได้รับการบำรุงรักษาทั่วโลก แต่ละคีย์ของแผนที่สอดคล้องกับวัตถุและวัตถุนี้จะต้องสร้างเพียงครั้งเดียว หากไม่มีค่าที่สอดคล้องกับคีย์ในแผนที่จะมีการสร้างขึ้นมิฉะนั้นจะถูกส่งคืนโดยตรง
มาดูรหัสก่อน:
สถานที่สาธารณะคงที่ getInstance (ภาษาสตริง, ประเทศสตริง, ตัวแปรสตริง) {// ... คีย์สตริง = some_string; locale locale = map.get (คีย์); if (locale == null) {locale = locale ใหม่ (ภาษา, ประเทศ, ตัวแปร); map.put (คีย์, locale); } คืนสถานที่; - รหัสนี้ต้องทำอะไรคือ:
เราคาดหวังว่าทุกครั้งที่มีการเรียกวิธีการ getInstance เราจะต้องตรวจสอบให้แน่ใจว่าคีย์เดียวกันส่งคืนการอ้างอิงวัตถุท้องถิ่นเดียวกัน รหัสนี้สามารถบรรลุข้อกำหนดนี้ได้หรือไม่?
คำตอบคือ: ข้อกำหนดสามารถปฏิบัติตามสภาพแวดล้อมแบบเธรดเดี่ยวได้ แต่จะมีปัญหาด้านความปลอดภัยของเธรดในสภาพแวดล้อมแบบมัลติเธรดนั่นคือไม่สามารถรับประกันได้ว่าคีย์เดียวกันในการพร้อมกันจะส่งคืนการอ้างอิงวัตถุท้องถิ่นเดียวกัน
นี่เป็นเพราะมีนิสัยในรหัสข้างต้นที่เรียกว่าการดำเนินการ put-if-absent [1] และการดำเนินการนี้มีเงื่อนไขการแข่งขัน:
if (locale == null) {locale = locale ใหม่ (ภาษา, ประเทศ, ตัวแปร); map.put (คีย์, locale); - เพราะหลังจากเธรดได้ตัดสินสถานที่ที่ดี == null จึงเป็นความจริงที่จะใส่ค่าในแผนที่ เธรดอื่น ๆ อาจทำไปแล้วใส่การดำเนินการบนแผนที่ เมื่อทำการดำเนินการอีกครั้งวัตถุในสถานที่ที่สอดคล้องกับคีย์เดียวกันจะถูกเขียนทับและในที่สุดการอ้างอิงสถานที่ของคีย์เดียวกันที่ส่งคืนโดยวิธี getInstance จะไม่สอดคล้องกัน ดังนั้นการดำเนินการ put-if-absent บนแผนที่จึงไม่ปลอดภัย (เธรดปลอดภัย)
เพื่อแก้ปัญหานี้ Java 5.0 ได้แนะนำอินเทอร์เฟซพร้อมกันที่พร้อมกันซึ่งมีการดำเนินการแบบ put-if-absent อยู่ในรูปแบบของวิธีการอะตอม putIfAbsent(K key, V value) ตามที่ Javadoc เขียน:
เมื่อเพิ่มคู่คีย์-ค่าลงในสายการผลิตพร้อมกันมันจะพิจารณาก่อนว่าคู่คีย์-ค่ามีอยู่แล้วหรือไม่
แก้ไขวิธีการข้างต้น:
สถานที่สาธารณะคงที่ getInstance (ภาษาสตริง, ประเทศสตริง, ตัวแปรสตริง) {// ... คีย์สตริง = some_string; locale locale = map.get (คีย์); if (locale == null) {locale = locale ใหม่ (ภาษา, ประเทศ, ตัวแปร); map.putifabsent (คีย์, locale); } คืนสถานที่; - รหัสนี้ใช้รูปแบบที่เกิดขึ้นพร้อมกันของ MAP (ConcurrentMap, ConcurrentHashMap) และใช้เพียงแค่ใช้แผนที่คำสั่ง map.putIfAbsent(key, locale) สิ่งนี้ยังไม่รับประกันว่าคีย์เดียวกันจะส่งคืนการอ้างอิงวัตถุสถานที่เดียวกัน
ข้อผิดพลาดที่นี่คือวิธีการ putifabsent มีค่าส่งคืนและค่าส่งคืนเป็นสิ่งสำคัญ
ดังนั้นเมื่อใช้วิธีการ putifabsent อย่าลืมตัดสินค่าผลตอบแทน
สถานที่สาธารณะคงที่ getInstance (ภาษาสตริง, ประเทศสตริง, ตัวแปรสตริง) {// ... คีย์สตริง = some_string; locale locale = map.get (คีย์); if (locale == null) {locale = locale ใหม่ (ภาษา, ประเทศ, ตัวแปร); locale tmp = map.putifabsent (คีย์, locale); if (tmp! = null) {locale = tmp; }} กลับ locale; - นำเข้า java.util.map; นำเข้า java.util.concurrent.concurrenthashmap; การทดสอบระดับสาธารณะ {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {// ทดสอบ currenthashmap.putifabsent () แผนที่ <long, string> clientmap = ใหม่ ครั้งแรก "); system.out.println (" clientmap: " + clientmap); system.out.println (); // เพิ่มระเบียนใหม่ใน clientmap ที่ว่างเปล่า system.out.println (" เพิ่มระเบียนใหม่ใน clientmap ที่ว่างเปล่า "); clientmap.putifabsent (netId, str1); system.out.println ("เพิ่มไคลเอ็นต์ก่อนหน้า:" + ไคลเอนต์ map); system.out.println ("ดูค่าคืนค่า:" + ผลลัพธ์); system.out.println (); result2 = clientmap.putifabsent (netId, str1); system.out.println ("หลังจากเพิ่มไคลเอนข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้เกี่ยวกับตัวอย่างการใช้งานของ ConcurrentMap.putifabsent (คีย์, ค่า) และฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน เพื่อนที่สนใจสามารถอ้างถึงหัวข้ออื่น ๆ ที่เกี่ยวข้องในเว็บไซต์นี้ต่อไป หากมีข้อบกพร่องใด ๆ โปรดฝากข้อความไว้เพื่อชี้ให้เห็น ขอบคุณเพื่อนที่ให้การสนับสนุนเว็บไซต์นี้!