def fetch(self, url):
for i in range(2):
title, images = build_fetch(url).fetch(url)
if images:
break
if images:
images = images[:150]
self._finished = False
self._total = len(images)
current = 0
while current < self._total:
self.pool.queueTask(self.check_image, images[current:current + self._per_check], self.collect_image)
current = current + self._per_check
from time import sleep
# 等待抓取完毕
while not self._finished:
sleep(0.05)
pass
return title, self._urls
根据 java api doc ,使用wait,notify注意事项:
1. 调用线程必须已经获得了object的锁,即在synchronized方法或者synchronized(object){}语句块中调用。
2. 调用线程被唤醒后实际上并不会立即执行后续操作,它要先和其它活动线程竞争获得当前对象的锁,得到对象锁后才能接着执行wait后代码。
下面是一个例子:
public class Tester3 {
public synchronized void take() {
System.out.println("take");
try {
Thread.currentThread().sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void put() {
System.out.println("put");
}
/**
* @param args
*/
public static void main(String[] args) {
final Tester3 tester = new Tester3();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("take begin");
tester.take();
System.out.println("take end");
}
});
t.start();
t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("put begin");
tester.put();
System.out.println("put end");
}
});
t.start();
}
}
输出(put必须等到get释放锁之后才能被执行):
take begin
put begin
take
take end
put
put end python
python对象没有隐式的和一个锁关联,且python中的 wait,notify是由python语言自身利用锁(Lock)实现,实现类为Condition,但是概念思想上是和java保留一致,如果要模拟 java的话,只需创建python对象时,显式将一个Condition实例赋给创建对象的一个成员属性,那么可以对应java中的doc来看一下 python的实现:
threading.py Condition类:
1。wait,notify必须在获得当前对象锁的前提下:
def wait(self, timeout=None):
if not self._is_owned():
raise RuntimeError("cannot wait on un-aquired lock")
.......
def notify(self, n=1):
if not self._is_owned():
raise RuntimeError("cannot notify on un-aquired lock")
.......
可见在wait,notify时都要进行检查,其中self._is_owned()正是判断调用线程是否获得了Condition的内置锁,也即java中对象monitor的概念。 2.wait调用后会使当前线程放弃已经获得对象锁: