生产者与消费者问题
- wait()和notify()¬ifyAll()必须工作在加锁(synchronized)的代码块中。
- 抢占的锁和释放的锁要是同一对象的锁,否则抛出IllegalMonitorStateException。
Stack.java
package thread;
public class Stack {
private Object[] objs;
private int index = 0;
public Stack() {
this(3);
}
public Stack(int length) {
this.objs = new Object[length];
}
public void push(Object obj) {
synchronized (this) {
while (index == this.objs.length) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < 100000; i++) {};
objs[index] = obj;
index++;
this.notifyAll();
}
}
public Object pop() {
synchronized (this) {
while (index == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
--index;
for (int i = 0; i < 100000; i++) {};
Object value = this.objs[index];
this.notifyAll();
return value;
}
}
}
Producer.java
package thread;
import java.util.Random;
public class Producer extends Thread{
private Stack stack;
public Producer(Stack stack){
this.stack = stack;
}
@Override
public void run() {
Random ran = new Random();
for (int i = 0; i < 20; i++) {
Object obj = ran.nextInt(200);
stack.push(obj);
System.out.println(obj+" 压入成功。" );
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Customer.java
package thread;
public class Customer extends Thread{
private Stack stack;
public Customer(Stack stack) {
this.stack = stack;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
Object value = stack.pop();
System.out.println(value+" 弹出成功。");
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Test.java
package thread;
public class Test {
public static void main(String[] args) {
Stack stack = new Stack();
for (int i = 0; i < 20; i++) {
Producer p = new Producer(stack);
p.setName("producerThread");
p.start();
}
for (int i = 0; i < 20; i++) {
Customer c = new Customer(stack);
c.setName("customerThread");
c.start();
}
}
}