เมื่อฉันเห็นคำถามนี้ครั้งแรกฉันไม่สามารถเริ่มต้นได้เพราะฉันรู้สึกว่าซิงโครไนซ์และล็อคแตกต่างกันมากในแง่ของการล็อค ตัวอย่างเช่นดูวิธีการล็อคเมื่อซิงโครไนซ์ภายใต้สถานการณ์ปกติ
วิธีที่ 1:
โมฆะที่ซิงโครไนซ์สาธารณะ A () {// toDo}วิธีที่ 2:
โมฆะสาธารณะ B () {ซิงโครไนซ์ (นี่) {// toDo}}จากสองวิธีนี้การล็อคจะถูกเพิ่มระหว่าง {} ลองมาดูกันว่าล็อคจะทำอย่างไร:
โมฆะสาธารณะ c () {lock.lock (); ลอง {// toDo} ในที่สุด {lock.unlock (); -วิธีการล็อคนี้จะถูกเพิ่มระหว่างล็อค () และปลดล็อค () ดังนั้นหากคุณต้องการใช้ฟังก์ชั่นล็อคคุณต้องคิดถึงวิธีการใช้วิธีการทั้งสองนี้คือ lock () และปลดล็อค () วิธีแรกกำหนดกรอบการทำงานดังนี้:
โมฆะสาธารณะล็อค () {} โมฆะสาธารณะปลดล็อค () {}จากนั้นคุณต้องคิดเกี่ยวกับวิธีการใช้การซิงโครไนซ์เพื่อใช้วิธีการทั้งสองนี้
ตอนนี้ฉันชัดเจนขึ้นเล็กน้อยในใจ แต่ฉันไม่รู้วิธีเติมสองวิธีนี้ นี่คือวิธีการวิเคราะห์ลักษณะของการล็อคของล็อคแล้วดูที่รหัสนี้:
โมฆะสาธารณะ c () {lock.lock (); // เมื่อเธรดปัจจุบันได้รับล็อคเธรดอื่น ๆ ต้องรอลอง {// เธรดปัจจุบันรับในล็อคเธรดอื่น ๆ ไม่สามารถรับได้ใน // todo} ในที่สุด {lock.unlock (); // เธรดปัจจุบันปล่อยล็อค}}}}ฉันเพิ่งเพิ่มความคิดเห็นเล็กน้อยเกี่ยวกับรหัสนี้และไม่ได้ทำอะไรอีก ช่วยให้เข้าใจรหัสนี้และดูว่าคำที่พบบ่อยที่สุดคืออะไร CurrentThread? ดังนั้นเมื่อเรากรอกวิธีการล็อค () และปลดล็อก () เราควรให้ความสนใจกับการจับคำหลัก currentThread เพื่อค้นหาวิธีแก้ปัญหาหรือไม่? คำตอบคือใช่
จากนั้นวิเคราะห์วิธีทำให้เธรดรอเมื่อใช้ซิงโครไนซ์? มันคือการใช้วิธีการรอ () จะปลุกเธรดได้อย่างไร? มันใช้วิธีการแจ้งเตือน () จากนั้นคุณต้องใช้วิธีการรอ () ในวิธีการล็อค () และวิธีการแจ้งเตือน () ในวิธีการปลดล็อค () ดังนั้นเมื่อเราใช้การรอ () และแจ้ง () เรามีเงื่อนไข คิดเกี่ยวกับสิ่งที่เราควรใช้เป็นเงื่อนไข?
เราควรใช้ว่าล็อคปัจจุบันถูกครอบครองเป็นเงื่อนไขการตัดสินหรือไม่ หากล็อคถูกครอบครอง ลองคิดดูว่าเราใช้เงื่อนไขนี้เมื่อใช้การซิงโครไนซ์หรือไม่ คำตอบคือใช่
มาวิเคราะห์ว่าจะปล่อยล็อคและเงื่อนไขใดบ้างที่ใช้ ลองคิดดูว่าเธรด A ได้รับล็อคหรือไม่เธรด B จะถูกปล่อยออกมาได้หรือไม่? ไม่แน่นอน หาก B สามารถปล่อยออกมาได้จะเป็นการละเมิดหลักการแน่นอนว่าไม่ แน่นอนว่าล็อคของเธรด A สามารถปล่อยออกมาได้เท่านั้น ดังนั้นเงื่อนไขการตัดสินคือการตัดสินว่าเธรดที่ถือล็อคนั้นเป็นกระแสไฟฟ้าหรือไม่ ถ้าเป็นเช่นนั้นสามารถปล่อยออกมาได้ แต่แน่นอนว่ามันไม่สามารถทำได้
มาดูรหัสที่สมบูรณ์ตอนนี้:
การทดสอบแพ็คเกจล็อค; นำเข้า java.util.random; นำเข้า java.util.concurrent.executorservice; นำเข้า java.util.concurrent.executors; นำเข้า java.util.concurrent.threadfactory; ไม่มี;} โมฆะที่ซิงโครไนซ์ล็อค () {Long currentThreadId = thread.currentThread (). getId (); ถ้า (เจ้าของ == currentThreadId) {โยนใหม่ legenlStateException ("ล็อคได้มาจากเธรดปัจจุบัน"); {wait ();} catch (interruptedException e) {e.printStackTrace ();}} เจ้าของ = currentthreadid; system.out.println (String.format ("ล็อคถูกซื้อโดย Thread %S", เจ้าของ); orderalStateException ("เจ้าของล็อคเท่านั้นที่สามารถปลดล็อคล็อค");} system.out.println (string.format ("Thread %S คือการปลดล็อค", เจ้าของ)); system.out.println (); เจ้าของ = ไม่มี; แจ้ง (); Executors.NewFixedThreadPool (20, ThreadFactory ใหม่ () {กลุ่ม ThreadGroup ส่วนตัว = ใหม่ ThreadGroup ("Test Thread Group"); {group.setDaemon (จริง);}@reverride เธรดสาธารณะ newThread (runnable r) {กลับมาใหม่ runnable () {@Override โมฆะสาธารณะเรียกใช้ () {lock.lock (); system.out.println (string.format ("เธรด %s กำลังทำงาน ... ", thread.currentthread (). getId ()); ลอง {thread.sleep {E.PrintStackTrace ();} lock.unlock ();}});}}}เรียกใช้และดูผลลัพธ์:
ล็อคจะได้มาโดยด้าย 8 เธรด 8 กำลังทำงานอยู่ ... ด้าย 27 กำลังรอล็อคด้าย 26 กำลังรอล็อคด้าย 25 กำลังรอล็อคเธรด 24 กำลังรอล็อคด้าย 23 รอล็อคด้าย 22 กำลังรอล็อคด้าย 21 กำลังรอล็อคด้าย 20 รอล็อคด้าย 19 กำลังรอล็อคด้าย 18 รอล็อคด้าย 27 เธรด 27 กำลังทำงานอยู่ ... เธรด 27 คือการปลดล็อคล็อคจะได้รับโดยเธรด 26 เธรด 26 กำลังทำงานอยู่ ... เธรด 26 คือการปลดล็อคล็อคจะได้มาจากเธรด 25 เธรด 25 กำลังทำงานอยู่ ... เธรด 25 กำลังปลดล็อคล็อคจะได้มาโดยด้าย 24 เธรด 24 กำลังทำงานอยู่ ... ด้าย 24 เธรด 20 เธรด 20 กำลังทำงานอยู่ ... เธรด 20 คือการปลดล็อคล็อคจะได้มาโดยด้าย 19 เธรด 19 กำลังทำงานอยู่ ... เธรด 19 คือการปลดล็อคล็อคจะได้มาจากเธรด 18 เธรด 18 กำลังทำงานอยู่ ... เธรด 18 คือการปลดล็อคล็อคจะได้มาโดยด้าย 17 เธรด 17 กำลังทำงานอยู่ ... เธรดที่ปลดล็อค โดยเธรด 13 เธรด 13 กำลังทำงานอยู่ ... เธรด 13 คือการปลดล็อคล็อคจะได้รับโดยเธรด 12 เธรด 12 กำลังทำงานอยู่ ... เธรด 12 คือการปลดล็อคล็อคจะได้รับโดยเธรด 11 เธรด 11 กำลังทำงานอยู่ ... เธรด 11 คือการปลดล็อคการล็อคจะได้มาโดยเธรด 10 เธรด 10 กำลังทำงานอยู่ ... เธรด 10 คือการปลดล็อค
หากคุณเปลี่ยนการวนรอบเป็น 30 ครั้งให้ดูที่ผลลัพธ์:
ล็อคจะได้มาโดยด้าย 8 เธรด 8 กำลังทำงานอยู่ ... ด้าย 27 กำลังรอล็อคด้าย 26 กำลังรอล็อคด้าย 25 กำลังรอล็อคเธรด 24 กำลังรอล็อคด้าย 23 รอล็อคด้าย 22 กำลังรอล็อคด้าย 21 กำลังรอล็อคด้าย 20 รอล็อคด้าย 19 กำลังรอล็อคด้าย 18 รอล็อคด้าย 27 เธรด 27 กำลังทำงานอยู่ ... เธรด 8 กำลังรอล็อคด้าย 27 คือการปลดล็อคล็อคจะได้รับโดยด้าย 27 เธรด 27 กำลังทำงานอยู่ ... เธรด 26 กำลังรอล็อคด้าย 27 กำลังปลดล็อคล็อคจะได้รับโดยเธรด 27 27 กำลังทำงานอยู่ ... เธรด 25 กำลังรอล็อค 27 คือการปลดล็อคล็อคอยู่ 23 เธรด 24 กำลังรอล็อคเธรด 22 คือการปลดล็อคล็อคจะได้มาโดยด้าย 22 เธรด 22 กำลังทำงานอยู่ ... เธรด 21 กำลังรอล็อคด้าย 22 คือการปลดล็อคล็อคจะได้รับโดยด้าย 22 เธรด 22 กำลังทำงานอยู่ ... ด้าย 20 กำลังรอล็อคด้าย 22 กำลังปลดล็อคล็อคจะได้รับโดยด้าย 22 เธรด 22 กำลังทำงานอยู่ เธรด 16 เธรด 16 กำลังทำงานอยู่ ... เธรด 16 คือการปลดล็อคล็อคจะได้รับโดยเธรด 15 เธรด 15 กำลังทำงานอยู่ ... เธรด 15 คือการปลดล็อคล็อคจะได้มาโดยเธรด 14 เธรด 14 กำลังทำงานอยู่ ... เธรด 14 คือการปลดล็อคล็อคจะได้มาโดยเธรด 13 เธรด 13 กำลังทำงานอยู่ โดยเธรด 9 เธรด 9 กำลังทำงานอยู่ ... เธรด 9 คือการปลดล็อคล็อคจะได้รับโดยเธรด 8 เธรด 8 กำลังทำงานอยู่ ... เธรด 8 คือการปลดล็อคล็อคจะได้มาจากเธรด 26 26 กำลังทำงานอยู่ ... เธรด 26 คือการปลดล็อคการล็อคนั้นได้มาจากเธรด 25 เธรด 25 กำลังทำงานอยู่ ได้มาจากเธรด 21 เธรด 21 กำลังทำงานอยู่ ... เธรด 21 คือการปลดล็อคล็อคจะได้มาโดยเธรด 20 เธรด 20 กำลังทำงานอยู่ ... เธรด 20 คือการปลดล็อคล็อคจะได้มาจากเธรด 19 เธรด 19 กำลังทำงานอยู่ ... เธรด 19 คือการปลดล็อคล็อคจะได้มาจากเธรด 18 เธรด 18 กำลังทำงานอยู่
สรุป
ข้างต้นเป็นคำอธิบายโดยละเอียดทั้งหมดของบทความนี้เกี่ยวกับการใช้การซิงโครไนซ์เพื่อใช้รหัสล็อค ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน เพื่อนที่สนใจสามารถอ้างถึงเว็บไซต์นี้ต่อไปได้:
Java Thread Synchronization Lock Synchronization Code ตัวอย่างตัวอย่าง
ความแตกต่างระหว่างการซิงโครไนซ์และล็อคในการเขียนโปรแกรม Java [แนะนำ]
Java MultithReaded ReadWriteLock รหัสการใช้งานการแยกการอ่าน-เขียน
หากมีข้อบกพร่องใด ๆ โปรดฝากข้อความไว้เพื่อชี้ให้เห็น ขอบคุณเพื่อนที่ให้การสนับสนุนเว็บไซต์นี้!