การแนะนำ
Java จัดเตรียมแพ็คเกจ java.util.concurrent.atomic ตั้งแต่ jdk1.5 ซึ่งอำนวยความสะดวกให้กับโปรแกรมเมอร์ในการดำเนินการอะตอมโดยไม่ต้องล็อคในสภาพแวดล้อมแบบมัลติเธรด ชั้นพื้นฐานของตัวแปรอะตอมใช้คำแนะนำอะตอมที่จัดทำโดยโปรเซสเซอร์ แต่สถาปัตยกรรม CPU ที่แตกต่างกันอาจให้คำแนะนำอะตอมที่แตกต่างกันและอาจต้องใช้รูปแบบของการล็อคภายในบางรูปแบบดังนั้นวิธีนี้ไม่สามารถตรวจสอบให้แน่ใจว่าเธรดไม่ได้ถูกบล็อก
การแนะนำแพ็คเกจอะตอม
มี 12 คลาสในแพ็คเกจอะตอมและวิธีการอัปเดตอะตอมสี่วิธีคือ: การอัพเดทแบบอะตอมประเภทพื้นฐาน, อาร์เรย์การอัพเดทอะตอม, การอ้างอิงการอัพเดทอะตอมและฟิลด์อัพเดทอะตอม คลาสในแพ็คเกจอะตอมนั้นถูกนำมาใช้โดยทั่วไปโดยใช้ UNSAFE
คลาส Atomic Update ประเภทคลาสพื้นฐาน
สำหรับการอัปเดตประเภทพื้นฐานผ่านวิธีอะตอมแพ็คเกจอะตอมมีสามคลาสต่อไปนี้:
Atomicboolean: การอัพเดท Atomic ประเภทบูลีน
Atomicinteger: การอัพเดทอะตอม
Atomiclong: การอัพเดท Atomic Long Long Integer
วิธีการทั่วไปของ Atomicinteger มีดังนี้:
int addandget (int delta): เพิ่มค่าอินพุตให้กับค่าในอินสแตนซ์ (ค่าใน atomicinteger) ในลักษณะอะตอมและส่งคืนผลลัพธ์
บูลีนเปรียบเทียบ (คาดว่าจะมีการอัปเดต int): หากค่าอินพุตเท่ากับค่าที่คาดหวังให้ตั้งค่าเป็นค่าอินพุตแบบอะตอม
int getandincrement (): เพิ่มค่าปัจจุบันเป็น 1 อะตอม หมายเหตุ: ค่าที่ส่งคืนที่นี่คือค่าก่อนการสร้างอัตโนมัติ
Void Lazyset (int newValue): ในที่สุดมันจะถูกตั้งค่าเป็น NewValue หลังจากใช้ lazyset เพื่อตั้งค่าเธรดอื่น ๆ อาจยังคงสามารถอ่านค่าเก่า int getandset (int newValue): มันถูกตั้งค่าเป็นค่าของ newValue ในลักษณะอะตอมและส่งคืนค่าเก่า
รหัสตัวอย่าง Atomicinteger มีดังนี้:
นำเข้า java.util.concurrent.atomic.atomicinteger; AtomicIntegerTest ระดับสาธารณะ {atomicinteger atomicinteger Ai = ใหม่ atomicinteger (1); โมฆะคงที่สาธารณะ (สตริง [] args) {system.out.Ut.println (ai.getandincrement ();เอาท์พุท
12
ของหวานหลังอาหารเย็น
แพ็คเกจอะตอมให้การอัปเดตอะตอมสามประเภทพื้นฐาน แต่ประเภทพื้นฐานของ Java ได้แก่ ถ่านลอยและสองเท่า ดังนั้นคำถามคือวิธีอัปเดตอะตอมพื้นฐานประเภทอื่น ๆ ชั้นเรียนในแพ็คเกจอะตอมจะถูกนำไปใช้โดยใช้ Unsafe มาดูซอร์สโค้ดที่ไม่ปลอดภัย เราพบว่าไม่ปลอดภัยมีเพียงสามวิธี CAS, เปรียบเทียบและแอปพลิเคชัน, sompereandswapint และเปรียบเทียบและ spoleandswaplong จากนั้นดูที่ซอร์สโค้ด Atomicboolean เราพบว่าครั้งแรกที่แปลงบูลีนเป็นจำนวนเต็มจากนั้นใช้การเปรียบเทียบและ swapint สำหรับ CAS ดังนั้นการอัปเดตอะตอมสองครั้งจึงสามารถนำไปใช้งานได้โดยใช้แนวคิดที่คล้ายกัน
คลาสอาร์เรย์อัปเดตอะตอม
แพ็คเกจอะตอมมีสามคลาสต่อไปนี้:
AtomicintegerArray: การปรับปรุงองค์ประกอบในอาร์เรย์จำนวนเต็ม
Atomiclongarray: องค์ประกอบการอัพเดทอะตอมในอาร์เรย์ยาว
AtomicreferenceArray: องค์ประกอบการอัพเดทอะตอมในอาร์เรย์ประเภทอ้างอิง
คลาส AtomicintegerArray ส่วนใหญ่ให้อะตอมเพื่ออัปเดตจำนวนเต็มในอาร์เรย์ วิธีการที่ใช้กันทั่วไปมีดังนี้
int addandget (int i, int delta): เพิ่มค่าอินพุตแบบอะตอมลงในดัชนีองค์ประกอบ I ในอาร์เรย์
บูลีนเปรียบเทียบ (int i, int คาดหวัง, การอัปเดต int): หากค่าปัจจุบันเท่ากับค่าที่คาดไว้องค์ประกอบที่ตำแหน่งอาร์เรย์ฉันจะตั้งค่าอะตอมเป็นค่าการอัปเดต
รหัสตัวอย่างมีดังนี้:
คลาสสาธารณะ AtomicintegerArrayTest {static int [] value = new int [] {1, 2}; atomicintegerArray atomicintegerArray (ค่า); void main (String [] args) {ai.getandset (0 3); System.out.println (ai.get (0)); system.out.println (ค่า [0]);}}เอาท์พุท
31
สิ่งที่คุณต้องทราบในคลาส AtomicintegerArray คือค่าอาร์เรย์จะถูกส่งผ่านผ่านวิธีตัวสร้างและจากนั้น AtomicintegerArray จะคัดลอกอาเรย์ปัจจุบันสำเนาดังนั้นเมื่อ AtomicintegerArray ปรับเปลี่ยนองค์ประกอบอาร์เรย์ภายใน
ประเภทอ้างอิงการอัปเดตอะตอม
Atomicinteger ซึ่งเป็นประเภทพื้นฐานสามารถอัปเดตตัวแปรหนึ่งตัวเท่านั้น หากคุณต้องการอัปเดตตัวแปรหลายตัวคุณต้องใช้อะตอมนี้เพื่ออัปเดตคลาสที่จัดทำตามประเภทการอ้างอิง แพ็คเกจอะตอมมีสามคลาสต่อไปนี้:
AtomicReference: อะตอมอัพเดตประเภทการอ้างอิง
AtomicReferenceFieldUpdater: ฟิลด์อัพเดทอะตอมในประเภทอ้างอิง
AtomicMarkableReference: การอัพเดทประเภทการอ้างอิงด้วยบิตเครื่องหมาย คุณสามารถอัปเดตบิตแท็กประเภทบูลีนและประเภทอ้างอิงได้ วิธีการก่อสร้างคือ AtomicMarkableReference (V InitialRef, Boolean Initialmark)
รหัสสำหรับการใช้ AtomicReference มีดังนี้:
Atomicreferencetest ระดับสาธารณะ {public static atomicreference <user> atomicuserref = new Atomicreference </user> <ผู้ใช้> (); โมฆะคงที่สาธารณะ (สตริง [] args) {ผู้ใช้ = ผู้ใช้ใหม่ ("conan", 15); Atomicuserref.set (ผู้ใช้) 17); AtomicUserRef.CompareAndset (ผู้ใช้, updateUser); system.out.println (Atomicuserref.get (). getName ()); system.out.println (Atomicuserref.get () old;} public String getName () {return name;} public int getold () {return old;}}}เอาท์พุท
Shinichi17
คลาสฟิลด์การอัพเดทอะตอม
หากเราต้องการเพียงฟิลด์บางอย่างในคลาสที่แน่นอนเราจำเป็นต้องใช้อะตอมเพื่ออัปเดตคลาสฟิลด์ แพ็คเกจอะตอมมีสามคลาสต่อไปนี้:
AtomicintegerfieldUpdater: ตัวอัปเดตสำหรับฟิลด์ที่อัพเดทจำนวนเต็มอะตอม
AtomiclongfieldUpdater: ตัวอัปเดตสำหรับการอัพเดทอะตอมฟิลด์จำนวนเต็มยาว
AtomicStampedReference: การอัพเดทประเภทการอ้างอิงด้วยหมายเลขเวอร์ชัน คลาสนี้เชื่อมโยงค่าจำนวนเต็มที่มีการอ้างอิงและสามารถใช้สำหรับอะตอมข้อมูลมากขึ้นและหมายเลขเวอร์ชันซึ่งสามารถแก้ปัญหา ABA ที่อาจเกิดขึ้นเมื่อใช้ CAS สำหรับการอัปเดตอะตอม
คลาสฟิลด์อัพเดทอะตอมเป็นคลาสนามธรรมและทุกครั้งที่ใช้พวกเขาจะต้องใช้วิธีการแบบคงที่ Newupdater เพื่อสร้างตัวอัปเดต ตัวดัดแปลงความผันผวนสาธารณะจะต้องใช้สำหรับฟิลด์ของคลาสการอัปเดตอะตอม
ขั้นตอนแรกคือเนื่องจากคลาสฟิลด์การอัพเดทอะตอมเป็นคลาสนามธรรมทุกครั้งที่คุณใช้วิธีการแบบคงที่ AtomicintegerfieldUpdater.NewUpDater คุณต้องสร้างตัวอัปเดตและคุณต้องตั้งค่าคลาสและคุณสมบัติที่คุณต้องการอัปเดต ขั้นตอนที่สองคือการอัปเดตฟิลด์ (คุณสมบัติ) ของชั้นเรียนจะต้องใช้ตัวดัดแปลงที่ระเหยได้สาธารณะ
รหัสตัวอย่างของ Atomicintegerfieldupdater มีดังนี้:
คลาสสาธารณะ AtomicintegerfieldUpDaterTest {Private Static AtomicintegerfieldUpdater <ผู้ใช้> a = AtomicintegerfieldUpdater.NewUpDater (user.class, "old"); โมฆะคงที่สาธารณะ (String [] args) 10); System.out.println (A.getandincrement (Conan)); System.out.println (a.get (conan));} ผู้ใช้ระดับสแตติกสาธารณะ {ชื่อสตริงส่วนตัวเอาท์พุท
1011
สรุป
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้เกี่ยวกับการแนะนำและการใช้แพ็คเกจอะตอมมัลติเธรด Java ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน เพื่อนที่สนใจสามารถอ้างถึงเว็บไซต์นี้ต่อไปได้:
รู้เบื้องต้นเกี่ยวกับวิธีการเขียนแบบจำลองผู้บริโภคการผลิตภายใต้เงื่อนไขที่แตกต่างกันใน Java multithreading
Java Multithreaded Programming Synchronizer Future และ FutureTask Parsing and Code ตัวอย่าง
คำอธิบายโดยละเอียดเกี่ยวกับล็อคจอแสดงผลแบบหลายเธรดและล็อคในตัว Java
หากมีข้อบกพร่องใด ๆ โปรดฝากข้อความไว้เพื่อชี้ให้เห็น