java多线程之wait(),notify(),notifyAll()的详解分析
java多线程之wait(),notify(),notifyAll()的详解分析
发布时间:2016-12-28 来源:查字典编辑
摘要:wait(),notify(),notifyAll()不属于Thread类,而是属于Object基础类,也就是说每个对象都有wait(),n...

wait(),notify(),notifyAll()不属于Thread类,而是属于Object基础类,也就是说每个对象都有wait(),notify(),notifyAll()的功能.因为每个对象都有锁,锁是每个对象的基础,当然操作锁的方法也是最基础了。

wait导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或被其他线程中断。wait只能由持有对像锁的线程来调用。

notify唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程(随机)。直到当前的线程放弃此对象上的锁,才能继续执行被唤醒的线程。同Wait方法一样,notify只能由持有对像锁的线程来调用.notifyall也一样,不同的是notifyall会唤配所有在此对象锁上等待的线程。

"只能由持有对像锁的线程来调用"说明wait方法与notify方法必须在同步块内执行,即synchronized(obj)之内.再者synchronized代码块内没有锁是寸步不行的,所以线程要继续执行必须获得锁。相辅相成。

看一个很经典的例子(生产者与消费者):

首先是消费者线程类:

复制代码 代码如下:

import java.util.List;

public class Consume implements Runnable {

private List container = null;

private int count;

public Consume(List lst) {

this.container = lst;

}

public void run() {

while (true) {

synchronized (container) {

if (container.size() == 0) {

try {

container.wait();// 容器为空,放弃锁,等待生产

} catch (InterruptedException e) {

e.printStackTrace();

}

}

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

container.remove(0);

container.notify();

System.out.println("我吃了" + (++count) + "个");

}

}

}

}

接下来是生产者线程类:

复制代码 代码如下:

import java.util.List;

public class Product implements Runnable {

private List container = null;

private int count;

public Product(List lst) {

this.container = lst;

}

public void run() {

while (true) {

synchronized (container) {

if (container.size() > MultiThread.MAX) {

// 如果容器超过了最大值,就不要在生产了,等待消费

try {

container.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

container.add(new Object());

container.notify();

System.out.println("我生产了" + (++count) + "个");

}

}

}

}

最后是测试类:

复制代码 代码如下:

import java.util.ArrayList;

import java.util.List;

public class MultiThread {

private List container = new ArrayList();

public final static int MAX = 5;

public static void main(String args[]) {

MultiThread m = new MultiThread();

new Thread(new Consume(m.getContainer())).start();

new Thread(new Product(m.getContainer())).start();

}

public List getContainer() {

return container;

}

public void setContainer(List container) {

this.container = container;

}

}

运行结果如下所示:

复制代码 代码如下:

我生产了1个

我吃了1个

我生产了2个

我生产了3个

我生产了4个

我生产了5个

我生产了6个

我生产了7个

我吃了2个

我生产了8个

我吃了3个

我生产了9个

我吃了4个

我吃了5个

我吃了6个

我吃了7个

我吃了8个

我生产了10个

我生产了11个

我吃了9个

我生产了12个

我吃了10个

......

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新Java学习
热门Java学习
编程开发子分类