I need a queue which can only ever contain unique items, so I wrote a basic class that contains a queue.Queue() paired with a list to hold the items in the queue.
I've tested the code myself and it seems to work great, but I'm unsure if it's truly thread safe and whether or not I actually need the threading.Lock().
I have two questions:
- Is the queue.Queue() thread safe on it's own? And is it safe to put items on to the queue in one thread while getting them from the queue in another thread?
- Do I need the threading.Lock() here to maintain thread-safety?
import threading
from queue import Empty, Queue
from typing import Any
class UniqueQueue:
"""
A thread safe queue which can only ever contain unique items.
"""
def __init__(self) -> None:
self._q = Queue()
self._items = []
self._l = threading.Lock()
def get(self, block: bool = False, timeout: float | None = None) -> Any:
with self._l:
try:
item = self._q.get(block=block, timeout=timeout)
except Empty:
raise
else:
self._items.pop(0)
return item
def put(self, item: Any, block: bool = False, timeout: float | None = None) -> None:
with self._l:
if item in self._items:
return None
self._items.append(item)
self._q.put(item, block=block, timeout=timeout)
def size(self) -> int:
return self._q.qsize()
def empty(self) -> bool:
return self._q.empty()