这三个方法由于需要控制对对象的控制权(monitor),所以属于Object而不是属于线程。
wait(),会把持有该对象线程的对象控制权交出去,然后处于等待状态。
notify(),会通知某个正在等待这个对象的控制权的线程可以继续运行。
nofifyAll(),会通知所有等待这个对象控制权的线程继续运行,如果有多个正在等待该对象控制权时,具体唤醒哪个线程,就由操作系统进行调度。
注意:
1.生产者,消费者必须要对同一份资源进行操作。
2.无论是执行对象的wait、notify还是notifyAll方法,必须保证当前运行的线程取得了该对象的控制权(monitor)
生产者:

package com.currentPro.waitAndnotify;
import java.util.ArrayList;
import java.util.List;
public class Producer implements Runnable{
private List<Integer> taskQueue = new ArrayList<Integer>();
//生产的量
private final int MAX_CAPACITY;
public Producer(List<Integer> sharedQueue,int size){
this.taskQueue = sharedQueue;
this.MAX_CAPACITY = size;
}
@Override
public void run()
{
int counter = 1;
while (true)
{
try
{
synchronized (taskQueue)
{
while (taskQueue.size() == MAX_CAPACITY)
{
System.out.println("Queue is full " + Thread.currentThread().getName() + " is waiting , size: " + taskQueue.size());
taskQueue.wait();
}
Thread.sleep(1000);
taskQueue.add(counter);
System.out.println("Produced: " + counter);
counter++;
//唤醒正在等待的消费者,但是消费者是不是能获取到资源,由系统调度。
taskQueue.notifyAll();
}
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}
}

消费者:

package com.currentPro.waitAndnotify;
import java.util.List;
public class Consumer implements Runnable{
private final List<Integer> taskQueue ;
public Consumer(List<Integer> sharedQueue){
this.taskQueue = sharedQueue;
}
@Override
public void run()
{
while (true)
{
try
{
synchronized (taskQueue)
{
while (taskQueue.isEmpty())
{
System.out.println("Queue is empty " + Thread.currentThread().getName() + " is waiting , size: " + taskQueue.size());
taskQueue.wait();
}
Thread.sleep(1000);
int i = (Integer) taskQueue.remove(0);
System.out.println("Consumed: " + i);
taskQueue.notifyAll();
}
} catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}
}

测试代码:

package com.currentPro.waitAndnotify;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) throws InterruptedException {
//共享资源
List<Integer> taskQueue = new ArrayList<Integer>();
int MAX_CAPACITY = 5;
//创建生产者线程
Thread producer = new Thread(new Producer(taskQueue,MAX_CAPACITY),"producer");
//创建消费者线程
Thread consumer = new Thread(new Consumer(taskQueue),"consumer");
consumer.start();
Thread.sleep(2000);
producer.start();
}
}

本文深入探讨了Java中线程同步的三大方法:wait(), notify() 和 notifyAll(),并详细介绍了它们如何通过控制对象的monitor来实现线程间的等待和唤醒。通过生产者-消费者模式的实例代码,展示了这些方法在实际应用中的使用方式。
1706

被折叠的 条评论
为什么被折叠?



