Python threading Lock Class

The threading.Lock class in Python's threading module provides a simple mechanism for mutual exclusion, allowing only one thread to access a resource at a time. This is useful for preventing race conditions in multithreaded programs.

Table of Contents

  1. Introduction
  2. threading.Lock Class Syntax
  3. Examples
    • Basic Usage
    • Using with Statement
    • Preventing Race Conditions
  4. Real-World Use Case
  5. Conclusion

Introduction

The threading.Lock class is used to implement locks in Python. Locks are used to synchronize threads and ensure that only one thread can access a resource or critical section of code at a time. This helps prevent race conditions where multiple threads modify shared data simultaneously.

threading.Lock Class Syntax

Here is how you create and use a lock with the threading.Lock class:

import threading

lock = threading.Lock()

Methods:

  • acquire(blocking=True, timeout=-1): Acquire the lock. If blocking is True (the default), the method will block until the lock is available. If blocking is False, the method will return immediately with True if the lock is acquired and False otherwise. timeout specifies the maximum time to wait for the lock.
  • release(): Release the lock. This should only be called by the thread that has acquired the lock.

Examples

Basic Usage

Create and use a lock to synchronize threads.

Example

import threading

lock = threading.Lock()

def critical_section():
    lock.acquire()
    try:
        # Critical section of code
        print(f"Thread {threading.current_thread().name} is running")
    finally:
        lock.release()

threads = []
for i in range(5):
    thread = threading.Thread(target=critical_section, name=f"Thread-{i}")
    threads.append(thread)
    thread.start()

for thread in threads:
    thread.join()

Using with Statement

Use the with statement to simplify the acquisition and release of the lock.

Example

import threading

lock = threading.Lock()

def critical_section():
    with lock:
        # Critical section of code
        print(f"Thread {threading.current_thread().name} is running")

threads = []
for i in range(5):
    thread = threading.Thread(target=critical_section, name=f"Thread-{i}")
    threads.append(thread)
    thread.start()

for thread in threads:
    thread.join()

Preventing Race Conditions

Use a lock to prevent race conditions when modifying shared data.

Example

import threading

lock = threading.Lock()
shared_data = 0

def increment():
    global shared_data
    for _ in range(100000):
        with lock:
            shared_data += 1

threads = []
for i in range(5):
    thread = threading.Thread(target=increment)
    threads.append(thread)
    thread.start()

for thread in threads:
    thread.join()

print(f"Final value of shared_data: {shared_data}")

Real-World Use Case

Synchronizing Access to a Database

Use a lock to synchronize access to a database or other shared resource.

Example

import threading
import sqlite3

lock = threading.Lock()

def access_database():
    with lock:
        conn = sqlite3.connect('example.db')
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM my_table")
        data = cursor.fetchall()
        conn.close()
        print(f"Thread {threading.current_thread().name} fetched {len(data)} rows")

threads = []
for i in range(5):
    thread = threading.Thread(target=access_database, name=f"Thread-{i}")
    threads.append(thread)
    thread.start()

for thread in threads:
    thread.join()

Conclusion

The threading.Lock class is used for synchronizing threads in Python. It helps prevent race conditions by ensuring that only one thread can access a resource or critical section of code at a time. Proper usage can significantly enhance the reliability and correctness of your multithreaded applications.

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare