import threading import unittest class ThreadSafeCounter: """A counter protected against concurrent access.""" def __init__(self, initial: int = 0) -> None: self._value = initial self._lock = threading.Lock() def increment(self, amount: int = 1) -> int: """Increase the counter and return its new value.""" with self._lock: self._value += amount return self._value def decrement(self, amount: int = 1) -> int: """Decrease the counter and return its new value.""" return self.increment(-amount) @property def value(self) -> int: """Return a consistent snapshot of the current value.""" with self._lock: return self._value class ThreadSafeCounterTests(unittest.TestCase): def test_basic_operations(self) -> None: counter = ThreadSafeCounter(10) self.assertEqual(counter.increment(5), 15) self.assertEqual(counter.decrement(3), 12) self.assertEqual(counter.value, 12) def test_concurrent_increments(self) -> None: counter = ThreadSafeCounter() thread_count = 8 increments_per_thread = 10_000 def worker() -> None: for _ in range(increments_per_thread): counter.increment() threads = [threading.Thread(target=worker) for _ in range(thread_count)] for thread in threads: thread.start() for thread in threads: thread.join() self.assertEqual(counter.value, thread_count * increments_per_thread) if __name__ == "__main__": unittest.main()