/**
* @author yangwl
*
* wait noify noifyall
* 注意 : 因为涉及到对象锁,他们必须都放在synchronized中来使用.
* wait和notify大概可以理解:当多个线程对公共资源同时访问时,人为有意的控制线程访问的顺序.以达到我们的目的,
* 那么,这时候,锁对象就是这个公共资源了.怎么表示一个线程获得了这个锁呢?
* 像这样: synchronized(obj) {} 这样就获得了资源锁,wait和notify的调用都在{}中,
* 这样,字面上就可以理解为执行同步块的线程可以决定是否调用wait或notify(要在同步块外调用,你当然决定不了当前哪个线程在调用)
* wait: 暂定当前正在执行的线程,并释放资源锁,让其他线程可以有机会运行(程序停顿在这一行).
* notify/notifyall: 唤醒因锁池中的线程,使之运行.
*
*
* 下面这个生产者消费者的例子:
* t1.start();
t2.start(); 启动两个线程
* 生产者队列如果满了,则暂定生产者线程并释放资源锁以便消费者线程可以获得锁
* 消费者线程获得锁,出队列以后 调用了notify唤醒锁池中的线程,下次可能消费者线程再次运行 ,也有可能消费者线程运行,取决于调度程序怎么调用了.
*
* 注意: wait以后,线程暂停 ,其他线程获得锁,执行
* notify 以后,由于当前线程没有被暂停,下次可能还会执行,也可能不会
*
*
* @author yangwl
*
* wait noify noifyall
* 注意 : 因为涉及到对象锁,他们必须都放在synchronized中来使用.
* wait和notify大概可以理解:当多个线程对公共资源同时访问时,人为有意的控制线程访问的顺序.以达到我们的目的,
* 那么,这时候,锁对象就是这个公共资源了.怎么表示一个线程获得了这个锁呢?
* 像这样: synchronized(obj) {} 这样就获得了资源锁,wait和notify的调用都在{}中,
* 这样,字面上就可以理解为执行同步块的线程可以决定是否调用wait或notify(要在同步块外调用,你当然决定不了当前哪个线程在调用)
* wait: 暂定当前正在执行的线程,并释放资源锁,让其他线程可以有机会运行(程序停顿在这一行).
* notify/notifyall: 唤醒因锁池中的线程,使之运行.
*
*
* 下面这个生产者消费者的例子:
* t1.start();
t2.start(); 启动两个线程
* 生产者队列如果满了,则暂定生产者线程并释放资源锁以便消费者线程可以获得锁
* 消费者线程获得锁,出队列以后 调用了notify唤醒锁池中的线程,下次可能消费者线程再次运行 ,也有可能消费者线程运行,取决于调度程序怎么调用了.
*
* 注意: wait以后,线程暂停 ,其他线程获得锁,执行
* notify 以后,由于当前线程没有被暂停,下次可能还会执行,也可能不会
*
*
*/
public class Test04 {
public static void main(String[] args) throws InterruptedException {
Queue buffer = new LinkedList<>();
int maxSize = 10;
Thread t1 = new Thread(new Producter(buffer, maxSize));
Thread t2 = new Thread(new Customer(buffer, maxSize));
t1.start();
t2.start();
}
}
class Producter implements Runnable {
Queue buffer;
int maxSize;
public Producter(Queue buffer, int maxSize) {
this.buffer = buffer;
this.maxSize = maxSize;
}
@Override
public void run() {
while(true) {
synchronized(buffer) {
while(buffer.size() == maxSize) {
System.out.println("队列已满,生产者线程暂停."+buffer.size());
try {
buffer.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Random random = new Random();
int i = random.nextInt();
System.out.println("Producing value : " + i + "-------size" + buffer.size());
buffer.add(i);
buffer.notifyAll();
}
}
}
}
class Customer implements Runnable {
Queue buffer;
int maxSize;
public Customer(Queue buffer, int maxSize) {
this.buffer = buffer;
this.maxSize = maxSize;
}
@Override
public void run() {
while(true) {
synchronized(buffer) {
while(buffer.isEmpty()) {
System.out.println("队列已空,消费者线程暂停."+buffer.size());
try {
buffer.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Consuming value : " + buffer.remove() + "-------size" + buffer.size());
buffer.notifyAll();
}
}
}
}