Logging after an infinite loop
The only way that this:
message = random.randint(1, 101)
logging.info("Producer_1 got message: %s", message)
is going to terminate is on an exception. That in itself isn't a bad thing - stop iteration exceptions are a common pattern in Python. ...
This code is broken.
Imagine an Account with $100, two threads, one depositing $1, the other withdrawing $50.
Thread one acquired lock1, and begins executing:
this.balance = getBalance() + amount;
and reads $100 ...
Thread two acquired lock2, reads the balance (still $100), subtracts $50, stores the new balance ($50) and releases lock2.
... (back to ...