wait()与notify()
就和每个Java 对象都有与其相关联的锁一样,每个对象都可以维持等待线程列表。当线程调用对象的wait() method 时,线程所占有的每一个锁都会被暂时释放,而线程会被加到那个对象的等待线程列表并停止运行。当另一个线程调用同一个对象的notifyAll() method 时,对象就会唤醒等待的线程并允许它们继续运行
/**
* 一个队列。有个线程会调用push()来把一个对象插入队列。
* 另一个线程会调用pop()将对象从队列取出。如果没有数据,pop()就
* 会等待,直到有数据为止。这里所使用的是wait()/notify()。
*wait()和notify()必须被使用在synchronized method或程序块中。在Java 5.0
* 中,要用java.util.concurrent.BlockingQueue来代替
*/
public class WaitingQueue<E> {
LinkedList<E> q = new LinkedList<E>(); // 存储对象的地方
public synchronized void push(E o) {
q.add(o); // 将对象添加到列表的末尾
this.notifyAll(); // 告诉等待中的线程,数据已准备好
}
public synchronized E pop() {
while(q.size() == 0) {
try { this.wait(); }
catch (InterruptedException ignore) {}
}
return q.remove(0);
}
}
join()
有时一个线程必须停止并等待另一个线程完成。你可以用join() method 来完成
List list; // 要被排序的详细列表;已在其他地方初始化
// 定义线程来排序列表:降低其优先级,以让它只
// 有在当前线程在等待I/O 时才开始运行
Thread sorter = newBackgroundSorter(list); // 先前已定义
sorter.setPriority(Thread.currentThread.getPriority()-1);// 降低优先级
sorter.start(); // 开始排序
// 同时,在原先的线程中从文件中读取数据
byte[] data = readData(); // 在其他地方定义的method
// 在能继续处理之前,列表需已被彻底排序,所以如果sorter线程
// 还没完成,则我们必须等它结束
try { sorter.join(); }catch(InterruptedException e) {}
对象锁针对整个对象,当某个线程执行a方法获取对象锁,在a()未执行完之前,该对象处于锁定状态,其他线程无法再执行a方法或b方法
public class TS {
synchronized public void a() throws InterruptedException{
String name = Thread.currentThread().getName();
System.out.println(name+": a()");
Thread.sleep(10000);
}
synchronized public void b(){
String name = Thread.currentThread().getName();
System.out.println(name+": b()");
for(int i=0;i<1000;i++);
}
}