注意,一般使用notifyAll,如果使用notify,则只会通知一个wait的线程,notifyAll可防止通知信号丢失
wait会释放锁,notify/notifyAll不会释放锁,需要等syn代码块执行完才会释放锁
package com.chapter1.ch1.wait;
public interface AbstractStorage {
void consume(int num);
void produce(int num);
}
package com.chapter1.ch1.wait;
import java.util.LinkedList;
public class Storage implements AbstractStorage {
private static final int MAX_SIZE = 100;
private LinkedList<Object> list = new LinkedList<Object>();
/**
* 消费
*/
@Override
public void consume(int num) {
synchronized (list) {
while (list != null && num > list.size()) {
System.out.println("要消费【" + num + "】,但仓库内只有" + "【" + list.size() + "】");
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < num; i++) {
list.remove();
}
System.out.println("已要消费【" + num + "】,仓库内剩余" + "【" + list.size() + "】");
// 通知生产方法上wait的线程不再wait
list.notifyAll();
}
}
@Override
public void produce(int num) {
synchronized (list) {
while (list != null && (num + list.size()) > MAX_SIZE) {
System.out.println("要生产【" + num + "】,但仓库内已有" + "【" + list.size() + "】,生产后大于100");
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < num; i++) {
list.add(new Object());
}
System.out.println("已生产【" + num + "】,仓库内剩余" + "【" + list.size() + "】");
// 通知生产方法上wait的线程不再wait
list.notifyAll();
}
}
}
package com.chapter1.ch1.wait;
public class Producer extends Thread {
private int num;
public AbstractStorage abstractStorage;
public Producer(AbstractStorage abstractStorage) {
this.abstractStorage = abstractStorage;
}
public void setNum(int num) {
this.num = num;
}
public void produce(int num) {
this.abstractStorage.produce(num);
}
@Override
public void run() {
produce(num);
}
}
package com.chapter1.ch1.wait;
public class Consumer extends Thread {
private int num;
public AbstractStorage abstractStorage;
public Consumer(AbstractStorage abstractStorage) {
this.abstractStorage = abstractStorage;
}
public void setNum(int num) {
this.num = num;
}
public void consumer(int num) {
this.abstractStorage.consume(num);
}
@Override
public void run() {
consumer(num);
}
}
package com.chapter1.ch1.wait;
public class WaitMain {
public static void main(String[] args) {
AbstractStorage storage = new Storage();
Producer p1 = new Producer(storage);
Producer p2 = new Producer(storage);
Producer p3 = new Producer(storage);
Producer p4 = new Producer(storage);
p1.setNum(10);
p2.setNum(10);
p3.setNum(10);
p4.setNum(80);
Consumer c1 = new Consumer(storage);
Consumer c2 = new Consumer(storage);
Consumer c3 = new Consumer(storage);
Consumer c4 = new Consumer(storage);
c1.setNum(5);
c2.setNum(5);
c3.setNum(90);
c4.setNum(1);
try {
p1.start();
Thread.sleep(1000);
p2.start();
Thread.sleep(1000);
p3.start();
Thread.sleep(1000);
p4.start();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
c1.start();
Thread.sleep(2000);
c2.start();
Thread.sleep(2000);
c3.start();
Thread.sleep(2000);
c4.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}