Question: ```
import threading

shared_balance = 0

class Deposit(threading.Thread):
    def run(self):
        for i in xrange(1000000):
            global shared_balance
            balance = shared_balance
            balance += 100
            shared_balance = balance

class Withdraw(threading.Thread):
    def run(self):
        for i in xrange(1000000):
            global shared_balance
            balance = shared_balance
            balance -= 100
            shared_balance = balance

thread1 = Deposit()
thread2 = Withdraw()

thread1.start()
thread2.start()

thread1.join()
thread2.join()

print shared_balance

```

Everytime I run this program it outputs a random number. If it deposits 100, 1 million times and withdraws 100, 1 million times then why isn't the output 0?

Answer: 
You need to use [threading.Lock](http://docs.python.org/2/library/threading.html#lock-objects) to access you variables safely : 

```
from threading import Thread, Lock

shared_balance = 0

class Deposit(Thread):
    def __init__(self, lock):
        super(Deposit, self).__init__()
        self.lock = lock
    def run(self):
        global shared_balance
        for i in xrange(1000000):
            with self.lock:
                shared_balance += 100

class Withdraw(Thread):
    def __init__(self, lock):
        super(Withdraw, self).__init__()
        self.lock = lock
    def run(self):
        global shared_balance
        for i in xrange(1000000):
            with self.lock:
                shared_balance -= 100

shared_lock = Lock()
thread1 = Deposit(shared_lock)
thread2 = Withdraw(shared_lock)

thread1.start()
thread2.start()

thread1.join()
thread2.join()

print shared_balance

```

Output :

```
>>> 0

```

Also, take a look at the bytecode generated for :

```
a = 0
def f():
    global a
    a += 10

```

Bytecode of "a += 10" :

```
 6 LOAD_GLOBAL              0 (a)     # Load global "a"  UNSAFE ZONE
 9 LOAD_CONST               2 (10)    # Load value "10"  UNSAFE ZONE
12 INPLACE_ADD                        # Perform "+="     UNSAFE ZONE
13 STORE_GLOBAL             0 (a)     # Store global "a" 
16 LOAD_CONST               0 (None)  # Load "None"
19 RETURN_VALUE                       # Return "None"  

```

In Python, a bytecode execution cannot be preempted. It makes it really convenient to use for threading. But in that case, it takes 4 bytecode executions to perform the '+=' operation. It means that any other bytecode of any other thread is suceptible to be executed between these bytecodes. This is what makes it unsafe and the reason why you should use locks.
You use two thread to operator one shared\_balance, the result is unforeseen.

For example,
now shared\_balance = 0
if thread1 do:

```
balance = shared_balance
            balance += 100

```

now thread1 balance =100 shared\_balance=0
then it turns to thread2:

```
balance = shared_balance
            balance -= 100

```

now thread2 balance =-100 shared\_balance=0

then it turns to thread1:

```
shared_balance = balance

```

now shared\_balance =100

at last it turns to thread2:

```
shared_balance = balance

```

now shared\_balance = -100

so , when loop end, the result is not 0.

If you want to get the result 0, you should add a lock to each loop.