
“สวัสดี อามีโก้!”
“สวัสดีคิม!”
"วันนี้ฉันจะบอกคุณเกี่ยวกับการทำงานพร้อมกัน"
" Concurrencyเป็นไลบรารีคลาส Java ที่รวมคลาสพิเศษที่ได้รับการปรับให้เหมาะสมสำหรับการทำงานจากหลายเธรด นี่เป็นหัวข้อที่น่าสนใจและครอบคลุมมาก แต่วันนี้เราจะมาแนะนำกัน แพ็คเกจนี้เรียกว่า java.util แพ็คเกจพร้อมกัน ฉันจะบอกคุณเกี่ยวกับคลาสที่น่าสนใจสองสามคลาส”
" ประเภทของอะตอม "
"คุณรู้อยู่แล้วว่าแม้แต่ count++ ไม่ใช่การดำเนินการที่ปลอดภัยสำหรับเธรด เมื่อตัวแปรเพิ่มขึ้นทีละ 1 การดำเนินการสามรายการจะเกิดขึ้นจริง ดังนั้น อาจมีความขัดแย้งเมื่อตัวแปรถูกเปลี่ยนแปลง"
“ใช่ เอลลีบอกฉันเมื่อไม่นานมานี้:”
หัวข้อที่ 1 | หัวข้อที่ 2 | ผลลัพธ์ |
---|---|---|
|
|
|
"ถูกต้อง จากนั้น 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);
}
"แพ็คเกจพร้อมกันมีข้อดีมากมาย เราแค่ต้องเข้าใจคลาสเหล่านี้เป็นอย่างดีเพื่อใช้งาน"
“เข้าใจแล้ว ขอบคุณคิม คลาสเหล่านี้น่าสนใจจริงๆ ฉันหวังว่าสักวันหนึ่งฉันจะเชี่ยวชาญพวกมันเหมือนคนเก่ง”
GO TO FULL VERSION