from __future__ import annotations import threading import unittest from concurrent.futures import ThreadPoolExecutor class ThreadSafeCounter: """A small integer counter protected by a lock.""" def __init__(self, initial: int = 0) -> None: self._value = initial self._lock = threading.Lock() @property def value(self) -> int: # Return a consistent snapshot of the current value. with self._lock: return self._value def increment(self, amount: int = 1) -> int: # Keep the read-modify-write operation atomic. with self._lock: self._value += amount return self._value def decrement(self, amount: int = 1) -> int: with self._lock: self._value -= amount return self._value def reset(self, value: int = 0) -> int: with self._lock: self._value = value return self._value class ThreadSafeCounterTests(unittest.TestCase): def test_basic_operations(self) -> None: counter = ThreadSafeCounter(2) self.assertEqual(counter.value, 2) self.assertEqual(counter.increment(), 3) self.assertEqual(counter.increment(4), 7) self.assertEqual(counter.decrement(2), 5) self.assertEqual(counter.reset(), 0) def test_concurrent_increments(self) -> None: counter = ThreadSafeCounter() workers = 8 increments_per_worker = 10_000 def increment_many() -> None: for _ in range(increments_per_worker): counter.increment() with ThreadPoolExecutor(max_workers=workers) as executor: futures = [executor.submit(increment_many) for _ in range(workers)] for future in futures: future.result() self.assertEqual(counter.value, workers * increments_per_worker) if __name__ == "__main__": unittest.main()