การทำงานพร้อมกัน, BlockingQueues (Java 7) - 1

“สวัสดี อามีโก้!”

“สวัสดีคิม!”

"วันนี้ฉันจะบอกคุณเกี่ยวกับการทำงานพร้อมกัน"

" Concurrencyเป็นไลบรารีคลาส Java ที่รวมคลาสพิเศษที่ได้รับการปรับให้เหมาะสมสำหรับการทำงานจากหลายเธรด นี่เป็นหัวข้อที่น่าสนใจและครอบคลุมมาก แต่วันนี้เราจะมาแนะนำกัน แพ็คเกจนี้เรียกว่า java.util แพ็คเกจพร้อมกัน ฉันจะบอกคุณเกี่ยวกับคลาสที่น่าสนใจสองสามคลาส”

" ประเภทของอะตอม "

"คุณรู้อยู่แล้วว่าแม้แต่ count++ ไม่ใช่การดำเนินการที่ปลอดภัยสำหรับเธรด เมื่อตัวแปรเพิ่มขึ้นทีละ 1 การดำเนินการสามรายการจะเกิดขึ้นจริง ดังนั้น อาจมีความขัดแย้งเมื่อตัวแปรถูกเปลี่ยนแปลง"

“ใช่ เอลลีบอกฉันเมื่อไม่นานมานี้:”

หัวข้อที่ 1 หัวข้อที่ 2 ผลลัพธ์
register1 = count;
register1++;
count = register1;
register2 = count;
register2++;
count = register2;
register1 = count;
register2 = count;
register2++;
count = register2;
register1++;
count = register1;

"ถูกต้อง จากนั้น Java ได้เพิ่มชนิดข้อมูลเพื่อดำเนินการเหล่านี้เป็นหนึ่งเดียว เช่น อะตอม (อะตอมไม่สามารถแบ่งแยกได้)"

"ตัวอย่างเช่น Java มีAtomicInteger, AtomicBoolean, AtomicDoubleเป็นต้น"

"สมมติว่าเราต้องสร้างคลาส «ตัวนับ»:"

ตัวอย่าง
class Counter
{
 private int c = 0;

 public void increment()
 {
  c++;
 }

 public void decrement()
 {
  c--;
 }

 public int value()
 {
  return c;
 }
}

"คุณจะทำให้อ็อบเจกต์ของเธรดคลาสนี้ปลอดภัยได้อย่างไร"

"ฉันจะทำให้วิธีการทั้งหมดซิงโครไนซ์และเสร็จสิ้น:"

ตัวอย่าง
class synchronized Counter
{
 private int c = 0;

 public synchronized void increment()
 {
  c++;
 }

 public synchronized void decrement()
 {
  c--;
 }

 public synchronized int value()
 {
  return c;
 }
}

"ทำได้ดีมาก แต่จะเป็นอย่างไรถ้าเราใช้ประเภทอะตอม:"

ตัวอย่าง
class AtomicCounter
{
 private AtomicInteger c = new AtomicInteger(0);

 public void increment()
 {
  c.incrementAndGet();
 }

 public void decrement()
 {
  c.decrementAndGet();
 }

 public int value()
 {
  return c.get();
 }
}

"ทั้งชั้นเรียนของคุณและชั้นเรียนของฉันทำงานในลักษณะเดียวกัน แต่ชั้นเรียนที่มี AtomicInteger ทำงานได้เร็วกว่า"

“อืม ต่างกันนิดหน่อย?”

"ใช่ จากประสบการณ์ของฉัน ฉันแนะนำให้นำหน้าด้วยซิงโครไนซ์เสมอ เฉพาะเมื่อโค้ดแอปพลิเคชันทั้งหมดได้รับการเขียนและกระบวนการเพิ่มประสิทธิภาพได้เริ่มขึ้นแล้ว คุณควรเริ่มเขียนโค้ดใหม่เพื่อใช้ประเภทอะตอม แต่ไม่ว่าในกรณีใด ฉันต้องการให้คุณ เพื่อให้ทราบว่ามีประเภทดังกล่าวอยู่ แม้ว่าคุณจะไม่ได้ใช้งาน แต่ก็มีโอกาสที่คุณจะพบรหัสที่ใช้อยู่เสมอ"

"ฉันเห็นด้วย นั่นสมเหตุสมผลแล้ว"

"ยังไงก็ตาม คุณสังเกตไหมว่าประเภทอะตอมไม่เปลี่ยนรูปตรงกันข้ามกับคลาสจำนวนเต็ม มาตรฐาน AtomicIntegerมีเมธอดสำหรับเปลี่ยนสถานะภายในของมัน"

"เข้าใจแล้ว เช่นเดียวกับStringและStringBuffer "

"ใช่ อะไรประมาณนั้น"

" คอลเลคชันที่ปลอดภัยสำหรับเธรด "

"เป็นตัวอย่างของคอลเลกชันดังกล่าว ฉันขอนำเสนอ ConcurrentHashMap คุณจะทำให้เธรด HashMap ปลอดภัยได้อย่างไร"

"ทำให้วิธีการทั้งหมดตรงกันหรือไม่"

"แน่นอน แต่ตอนนี้ลองนึกภาพว่าคุณมี SynchronizedHashMap ดังกล่าวหนึ่งรายการ และมีเธรดมากมายที่เข้าถึงมัน และรายการใหม่จะถูกเพิ่มลงในแผนที่หนึ่งร้อยครั้งต่อวินาที และในกระบวนการนี้ วัตถุทั้งหมดจะถูกล็อคสำหรับการอ่านและเขียน"

"นี่เป็นวิธีมาตรฐาน คุณทำอะไรได้บ้าง"

"ผู้สร้างของ Java มาพร้อมกับสิ่งดีๆ สองสามอย่าง"

"อย่างแรก พวกเขาเก็บข้อมูลใน ConcurrentHashMap ในบล็อกเดียว แต่แบ่งออกเป็นส่วนๆ ที่เรียกว่า 'บัคเก็ต' และเมื่อมีคนเปลี่ยนข้อมูลใน ConcurrentHashMap เราจะล็อคเฉพาะบัคเก็ตที่กำลังเข้าถึง แทนที่จะเป็นออบเจกต์ทั้งหมด ในส่วนอื่นๆ คำพูดหลายเธรดสามารถเปลี่ยนวัตถุพร้อมกันได้ "

"อย่างที่สอง คุณจำได้ไหมว่าคุณไม่สามารถวนซ้ำองค์ประกอบของรายการ/แผนที่และเปลี่ยนรายการพร้อมกันได้? รหัสดังกล่าวจะส่งข้อยกเว้น:"

อย่าวนซ้ำองค์ประกอบของคอลเลกชันในลูปและเปลี่ยนพร้อมกัน
HashMap<String, Integer> map = new HashMap<String, Integer>();

for (String key: map.keySet())
{
 if (map.get(key) == 0)
  map.remove(key);
}

"แต่ใน ConcurrentHashMap คุณสามารถ:"

อย่าวนซ้ำองค์ประกอบของคอลเลกชันในลูปและเปลี่ยนพร้อมกัน"
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>();

for (String key: map.keySet())
{
 if (map.get(key) == 0)
  map.remove(key);
}

"แพ็คเกจพร้อมกันมีข้อดีมากมาย เราแค่ต้องเข้าใจคลาสเหล่านี้เป็นอย่างดีเพื่อใช้งาน"

“เข้าใจแล้ว ขอบคุณคิม คลาสเหล่านี้น่าสนใจจริงๆ ฉันหวังว่าสักวันหนึ่งฉันจะเชี่ยวชาญพวกมันเหมือนคนเก่ง”