Site Search:

Concurrent Collections: Java vs Python

Back>

Concurrent Collections: Java vs Python

While Java offers a formal package java.util.concurrent for concurrent collections, Python takes a more minimal approach, combining built-in thread-safe types, manual locking, and optional third-party libraries. Here's a comparison of the most commonly used concurrent collections and their equivalents in Python.

Java Concurrent Collection Python Equivalent Thread Safe? Notes
ConcurrentHashMap dict + threading.Lock
or multiprocessing.Manager().dict()
Partial (Manual Locking Required) No built-in atomic operations; use lock or external lib like concurrentmap
CopyOnWriteArrayList Custom logic using copy() of list No No built-in support; copy-on-write must be implemented manually
ConcurrentLinkedQueue queue.Queue Yes FIFO queue, thread-safe, includes blocking behavior
BlockingQueue queue.Queue Yes Offers put(), get() with timeout/blocking
BlockingDeque collections.deque + threading.Condition Partial Thread-safe for single-thread appends/pops; use lock for coordination
PriorityBlockingQueue queue.PriorityQueue Yes Thread-safe priority-based queue using heapq internally
SkipListMap / ConcurrentSkipListMap sortedcontainers Depends on Implementation Not built-in; SortedDict from sortedcontainers is a good alternative

Below are Python examples for working with thread-safe collections, equivalent to those in Java's java.util.concurrent package. While Python does not have built-in concurrent maps or copy-on-write lists, it provides safe queues and allows you to build thread-safe structures using locks or third-party modules.

1. Thread-Safe Queue (Equivalent to Java's BlockingQueue)

import queue
from threading import Thread

q = queue.Queue()

def producer():
    for i in range(5):
        q.put(f"Item {i}")
        print(f"Produced Item {i}")

def consumer():
    while not q.empty():
        item = q.get()
        print(f"Consumed {item}")
        q.task_done()

Thread(target=producer).start()
Thread(target=consumer).start()
---

2. Thread-Safe Priority Queue (Similar to PriorityBlockingQueue)

import queue
from threading import Thread

pq = queue.PriorityQueue()

pq.put((2, "low priority"))
pq.put((1, "high priority"))

def consume():
    while not pq.empty():
        priority, task = pq.get()
        print(f"Processing: {task}")
        pq.task_done()

Thread(target=consume).start()
---

3. Thread-Safe Dictionary Using Lock (Equivalent to ConcurrentHashMap)

from threading import Lock, Thread

safe_dict = {}
lock = Lock()

def safe_put(key, value):
    with lock:
        safe_dict[key] = value

def safe_get(key):
    with lock:
        return safe_dict.get(key)

Thread(target=safe_put, args=("a", 1)).start()
Thread(target=safe_put, args=("b", 2)).start()
---

4. Shared Dictionary Across Processes (Multiprocessing)

from multiprocessing import Process, Manager

manager = Manager()
shared_dict = manager.dict()

def writer():
    shared_dict["data"] = 42

def reader():
    print("Read:", shared_dict.get("data"))

p1 = Process(target=writer)
p2 = Process(target=reader)

p1.start()
p2.start()

p1.join()
p2.join()
---

5. Simulated Copy-On-Write List

import copy
from threading import Lock

class CopyOnWriteList:
    def __init__(self):
        self._lock = Lock()
        self._list = []

    def add(self, item):
        with self._lock:
            new_list = copy.copy(self._list)
            new_list.append(item)
            self._list = new_list

    def snapshot(self):
        return self._list

cow_list = CopyOnWriteList()
cow_list.add("Hello")
print(cow_list.snapshot())
---

6. Sorted Dictionary with sortedcontainers (Like SkipListMap)

from sortedcontainers import SortedDict

s = SortedDict()
s["b"] = 2
s["a"] = 1
print(list(s.items()))  # Output: [('a', 1), ('b', 2)]

Note: sortedcontainers must be installed via pip install sortedcontainers.

---

Conclusion

  • For basic thread-safe queues, use the queue module.
  • For shared dictionaries or lists, use locks or multiprocessing.Manager().
  • For performance-critical or atomic operations, third-party libraries or C extensions may be required.

Python doesn't include a dedicated concurrent collections package like Java's, but it provides the core building blocks to achieve thread and process safety using locks, queues, and managers. For more advanced use cases, third-party libraries like concurrentmap or sortedcontainers fill the gap.

No comments:

Post a Comment