Lock(), UnLock(), ReentrantLock(), TryLock() คืออะไร และแตกต่างจาก Synchronized Block ใน Java อย่างไร]
เผยแพร่แล้ว: 2020-07-05
ในบทช่วยสอนนี้ เราจะพูดถึง Lock(), UnLock(), ReentrantLock(), TryLock() และความแตกต่างจาก Synchronized Block ใน Java
หากคุณมีคำถามด้านล่างแสดงว่าคุณมาถูกที่แล้ว
- ล็อคใน Java
- ตัวอย่าง Java Lock และ Concurrency Lock เทียบกับการซิงโครไนซ์
- บทช่วยสอนการทำงานพร้อมกันของ Java – Reentrant Locks
- การซิงโครไนซ์ – การใช้การล็อก/ปลดล็อกอย่างเหมาะสมสำหรับ Java
- java – การซิงโครไนซ์กับ Lock
- ตัวอย่างการปลดล็อกจาวาล็อค
- กลไกการล็อคใน java
- จาวาล็อคปลดล็อคเธรดที่แตกต่างกัน
มาเริ่มกันเลย. อันดับแรก มาทำความเข้าใจคำศัพท์แต่ละคำกันก่อน จากนั้นเราจะมาดูตัวอย่างการทำงานกัน
ล็อค():
java.util.concurrent.locks
. ล็อกเป็นกลไกการซิงโครไนซ์เธรด เช่น บล็อกที่ซิงโครไนซ์ ยกเว้นการล็อกอาจซับซ้อนกว่าบล็อกที่ซิงโครไนซ์ของ Java เป็นอินเทอร์เฟซและคลาสที่จัดเตรียมกรอบงานสำหรับการล็อกและรอเงื่อนไขที่แตกต่างจากการซิงโครไนซ์ในตัวและการมอนิเตอร์
ปลดล็อค():
UnLock() ปลดล็อคบน Object
ReentrantLock():
ReentrantLock
เป็น ของเธรดล่าสุดที่ล็อกได้สำเร็จ แต่ยังไม่ได้ปลดล็อก lock
ที่เรียกใช้เธรดจะส่งคืน โดยได้รับล็อกสำเร็จ เมื่อเธรดอื่นไม่ได้เป็นเจ้าของการล็อก เมธอดจะส่งคืนทันทีหากเธรดปัจจุบันเป็นเจ้าของการล็อกอยู่แล้ว
TryLock():
TryLock() จะได้รับล็อคก็ต่อเมื่อว่างในขณะที่ร้องขอ
เคล็ดลับ-1
หากคุณเพียงแค่ล็อกวัตถุ ฉันต้องการใช้ synchronized.
1 2 3 |
Lock . lock ( ) ; youMethod ( ) ; // Throws a NullPointerException! Lock . unlock ( ) ; // Here you never release the lock! |
ในขณะที่ซิงโครไนซ์ มันชัดเจนมากและเป็นไปไม่ได้ที่จะผิดพลาด:
1 2 3 |
synchronized ( myObject ) { doSomethingNifty ( ) ; } |
รายละเอียดตัวอย่าง:
- สร้างคลาส: CrunchifyLockTutorial.java
- สร้างคลาสภายใน: บริษัท และ CrunchifyLoop
- จาก Main สร้างสองวัตถุของคลาส Company
- เริ่มการวนซ้ำของเธรดสำหรับ 10 บนอ็อบเจ็กต์เหล่านั้น
- ในขณะที่ Company1 คุยกับ Company2 – มันล็อคอ็อบเจกต์ หากในเวลาเดียวกัน – หาก
Company2
ต้องการพูดคุยกับCompany1
จะมีข้อความว่า – Conflicting – Lock มีอยู่แล้ว (ทั้งสองบริษัทอยู่ระหว่างการเจรจา)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
package crunchify . com . tutorial ; import java . util . Random ; import java . util . concurrent . locks . Lock ; import java . util . concurrent . locks . ReentrantLock ; /** * @author Crunchify.com * */ public class CrunchifyLockTutorial { public static void main ( String [ ] args ) { final Company crunchify = new Company ( "Crunchify" ) ; final Company google = new Company ( "Google" ) ; new Thread ( new CrunchifyLoop ( crunchify , google ) ) . start ( ) ; new Thread ( new CrunchifyLoop ( google , crunchify ) ) . start ( ) ; } // Class CrunchifyLoop static class CrunchifyLoop implements Runnable { private Company companyName1 ; private Company companyName2 ; public CrunchifyLoop ( Company companyName1 , Company companyName2 ) { this . companyName1 = companyName1 ; this . companyName2 = companyName2 ; } public void run ( ) { Random random = new Random ( ) ; // Loop 10 for ( int counter = 0 ; counter < = 10 ; counter ++ ) { try { Thread . sleep ( random . nextInt ( 5 ) ) ; } catch ( InterruptedException e ) { } companyName2 . crunchifyTalking ( companyName1 ) ; } } } // Class Company static class Company { private final String companyName ; // ReentrantLock: Creates an instance of ReentrantLock. This is equivalent to using ReentrantLock(false) private final Lock lock = new ReentrantLock ( ) ; // Constructor public Company ( String name ) { this . companyName = name ; } public String getName ( ) { return this . companyName ; } public boolean isTalking ( Company companyName ) { Boolean crunchifyLock = false ; Boolean googleLock = false ; try { // tryLock: Acquires the lock only if it is free at the time of invocation. crunchifyLock = lock . tryLock ( ) ; googleLock = companyName . lock . tryLock ( ) ; } finally { if ( ! ( crunchifyLock && googleLock)) { if (crunchifyLock) { // unlock: Releases the lock. lock.unlock(); } if ( googleLock ) { companyName . lock . unlock ( ) ; } } } return crunchifyLock && googleLock; } public void crunchifyTalking ( Company companyName ) { // Check if Lock is already exist? if ( isTalking ( companyName ) ) { try { System . out . format ( "I'm %s: talking to %s %n" , this . companyName , companyName . getName ( ) ) ; } finally { lock . unlock ( ) ; companyName . lock . unlock ( ) ; } } else { System . out . format ( "\tLock Situation ==> I'm %s: talking to %s, but it seems" + " we are already talking. Conflicting. %n" , this . companyName , companyName . getName ( ) ) ; } } } } |
เอาท์พุท:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
I 'm Crunchify: talking to Google Lock Situation ==> I' m Google : talking to Crunchify , but it seems we are already talking . Conflicting . I 'm Google: talking to Crunchify I' m Google : talking to Crunchify I 'm Crunchify: talking to Google I' m Google : talking to Crunchify I 'm Google: talking to Crunchify I' m Crunchify : talking to Google Lock Situation == > I 'm Google: talking to Crunchify, but it seems we are already talking. Conflicting. Lock Situation ==> I' m Crunchify : talking to Google , but it seems we are already talking . Conflicting . Lock Situation == > I 'm Google: talking to Crunchify, but it seems we are already talking. Conflicting. I' m Crunchify : talking to Google I 'm Google: talking to Crunchify I' m Google : talking to Crunchify I 'm Crunchify: talking to Google I' m Google : talking to Crunchify Lock Situation == > I 'm Google: talking to Crunchify, but it seems we are already talking. Conflicting. Lock Situation ==> I' m Crunchify : talking to Google , but it seems we are already talking . Conflicting . I 'm Crunchify: talking to Google I' m Crunchify : talking to Google I 'm Crunchify: talking to Google I' m Crunchify : talking to Google |
เคล็ดลับ-2

คุณสามารถบรรลุทุกสิ่งที่ยูทิลิตี้ใน java.util.concurrent
ทำกับ primitives ระดับต่ำ เช่น synchronized
, volatile
หรือ wait