threading.Condition

Conditionという排他オブジェクトです。

import time
import threading

class MyThread(threading.Thread):

    lock = threading.Lock()

    def __init__(self, name, lifetime, condition):
        threading.Thread.__init__(self)
        self.lifetime = lifetime
        self.condition = condition
    def run(self):
        while not self.lifetime <= 0:
            self.lifetime -= 1
            with self.lock:
                time.sleep(0.3)
                print threading.current_thread().getName(), "life is " , self.lifetime
        with self.condition:
            print threading.current_thread().getName(), "acquire"
            self.condition.notify()

def main():
    condition = threading.Condition(threading.Lock())
    t1 = MyThread("t1", 5, condition)
    t2 = MyThread("t2", 5, condition)
    t1.start()
    t2.start()
    fact = 0
    while fact < 5:
        with condition:
            condition.wait()
            if not t1.isAlive():
                t1 = MyThread("t1_" + str(fact), 5, condition)
                t1.start()
            else:
                t2 = MyThread("t2_" + str(fact), 5, condition)
                t2.start()
            fact += 1

    t1.join()
    t2.join()

if __name__ == '__main__':
    main()

threading.Thread.isAliveはスレッドが走っているかどうかを返します。

acquire()とrelease()使わずにwithステートメントを使用しています。
condition.acquireが呼び出されると、そこで内部にあるLockオブジェクトで
condition.releaseが呼び出されるか、condition.waitが呼び出されるまでブロックします
waitで待機してるオブジェクトはcondition.notify、またはcondition.notifyAllで起こすことができます。
注意しなければいけないのはwaitもnotifyもロックを取得してる中で行わないと、例外RuntimeErrorが発生します。
notifyを呼び出し、releaseを呼び出したタイミングがwaitで待つオブジェクトが再開するタイミングです。
また内部のLockオブジェクトはコンストラクタで指定することができます。

class _Condition(_Verbose):
    def __init__(self, lock=None, verbose=None):
        _Verbose.__init__(self, verbose)
        if lock is None:
            lock = RLock()
        self.__lock = lock

デフォルトだとthreading.RLockオブジェクトです。
RLock(reentrant lock)はacquire/releaseをネストできるオブジェクトです。
acquireしてから更にacquireが呼び出せます。そしてacquireした分だけreleaseしないとロックは解放されません。