← Back to Advanced Java Course | Chapter 11: Advanced & Security | Lesson 9 of 19

Java Locks और Semaphores

Locks और semaphores नियंत्रित करते हैं कि एक समय में कितने threads किसी चीज़ का उपयोग कर सकते हैं, जैसे एक कमरे की एक चाबी या सीमित seats के लिए tickets। वे threads को टकराने से रोकते हैं।
Syntax
java
Lock lock = new ReentrantLock();
lock.lock();
try {
    // critical section
} finally {
    lock.unlock();
}

ReentrantLock Basics

ReentrantLock synchronized keyword का एक ज़्यादा flexible, explicit विकल्प है। इसे acquire करने के लिए आपको lock() call करना चाहिए और इसे release करने के लिए finally block के अंदर unlock() call करना चाहिए, क्योंकि synchronized blocks के विपरीत, JVM किसी exception के फेंके जाने पर आपके लिए ReentrantLock को अपने आप release नहीं करता।

उदाहरण: ReentrantLock Basics

java
import java.util.concurrent.locks.ReentrantLock;
public class Main {
	static final ReentrantLock lock = new ReentrantLock();
	public static void main(String[] args) {
		lock.lock();
		try {
			System.out.println("Critical section");
		} finally {
			lock.unlock(); // must release manually, unlike synchronized
		}
	}
}

Non-Blocking Locks with tryLock()

tryLock() calling thread को block किए बिना एक lock acquire करने की कोशिश करता है -- अगर lock खाली था तो यह तुरंत true return करता है, या अगर नहीं था तो तुरंत false, एक thread को busy resource के लिए अनिश्चित काल तक इंतज़ार करने के बजाय कुछ और करने का फैसला करने देते हुए।

उदाहरण: Non-Blocking Locks with tryLock()

java
import java.util.concurrent.locks.ReentrantLock;
public class Main {
	static final ReentrantLock lock = new ReentrantLock();
	public static void main(String[] args) {
		if (lock.tryLock()) { // returns immediately instead of blocking
			try { System.out.println("Acquired the lock"); } finally { lock.unlock(); }
		} else {
			System.out.println("Lock was busy, doing something else");
		}
	}
}

ReadWriteLock

ReadWriteLock किसी भी संख्या में threads को एक साथ किसी shared resource को पढ़ने देकर throughput सुधारता है, जबकि यह अब भी गारंटी देता है कि एक समय में सिर्फ एक thread write lock रख सकता है और writes सभी reads के साथ exclusive हैं -- उन data के लिए आदर्श जो modify होने से कहीं ज़्यादा बार पढ़ा जाता है।

उदाहरण: ReadWriteLock

java
import java.util.concurrent.locks.*;
public class Main {
	static final ReadWriteLock rwLock = new ReentrantReadWriteLock();
	public static void main(String[] args) {
		rwLock.readLock().lock(); // multiple readers allowed at once
		try { System.out.println("Reading"); } finally { rwLock.readLock().unlock(); }
		rwLock.writeLock().lock(); // exclusive of all reads and other writes
		try { System.out.println("Writing"); } finally { rwLock.writeLock().unlock(); }
	}
}

Semaphore Basics

एक Semaphore permits का उपयोग करके किसी resource के एक सीमित pool तक access control करता है: threads आगे बढ़ने से पहले एक permit लेने के लिए acquire() call करते हैं और बाद में उसे वापस देने के लिए release() call करते हैं, जो यह cap करने का standard तरीका है कि कितने threads एक साथ किसी चीज़ का उपयोग कर सकते हैं, जैसे एक fixed-size connection pool।

उदाहरण: Semaphore Basics

java
import java.util.concurrent.Semaphore;
public class Main {
	public static void main(String[] args) throws InterruptedException {
		Semaphore semaphore = new Semaphore(2); // 2 permits, like a connection pool of size 2
		semaphore.acquire();
		System.out.println("Permit acquired, available: " + semaphore.availablePermits());
		semaphore.release();
	}
}

Fair Lock Queueing

Default रूप से, Java locks इस बात की कोई गारंटी नहीं देते कि waiting threads किस order में किसी contested lock को acquire करेंगे। किसी ReentrantLock के constructor में fairness enable करना lock को उस thread को access देने के लिए मजबूर करता है जो सबसे लंबे समय से इंतज़ार कर रहा हो, raw throughput की कुछ कीमत पर।

उदाहरण: Fair Lock Queueing

java
import java.util.concurrent.locks.ReentrantLock;
public class Main {
	public static void main(String[] args) {
		ReentrantLock fairLock = new ReentrantLock(true); // grants access in waiting order
		fairLock.lock();
		try { System.out.println("Longest-waiting thread goes first"); } finally { fairLock.unlock(); }
	}
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. finally block में unlock() call न करना, जिससे किसी exception के कारण lock पकड़ा रह जाता है और दूसरे threads हमेशा के लिए इंतज़ार करते हैं।
  2. tryLock() से return हुए boolean को नज़रअंदाज़ करना और lock न मिलने पर भी protected code चलाना।
  3. किसी Semaphore पर acquire() call करना और finally में release() call न करना, जिससे permits leak होते हैं और threads block होते हैं।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.