1.实际应用场景:生产者-消费者问题
分析:
2.线程通信
3.用线程通信来解决生产者-消费者问题
- 管程法
- 信号灯法
4.管程法
具体代码如下:
public class D24 {
public static void main(String[] args) {
Basket basket = new Basket();
new Producer(basket).start();
new Consumer(basket).start();
}
}
class Bread {
int id;
public Bread(int id) {
this.id = id;
}
}
class Basket{
Bread[] bread = new Bread[8];
int num = 0;
public synchronized void push(Bread b){
while(num >= bread.length){
try {
this.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
bread[num++] = b;
this.notifyAll();
}
public synchronized Bread pop(){
while(num<=0){
try {
this.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
Bread b2 = bread[--num];
this.notifyAll();
return b2;
}
}
class Producer extends Thread{
Basket basket;
Producer(Basket basket){
this.basket = basket;
}
@Override
public void run() {
for(int i=0;i<100;i++){
basket.push(new Bread(i));
System.out.println("push bread " + i);
}
}
}
class Consumer extends Thread{
Basket basket;
Consumer(Basket basket){
this.basket = basket;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("pop bread " + basket.pop().id);
}
}
}
当缓冲区已满时,生产者应当wait()
当缓冲区为空时,消费者应当wait()
当生产者向缓冲区成功放入产品后,应notifyAll()来通知正在等待的消费者。
当消费者向缓冲区成功取走产品后,应notifyAll()来通知正在等待的生产者。
wait()方法
使当前线程等待,直到另一个线程调用此对象的notify()方法或notifyAll()方法。
当前线程必须拥有此对象的监视器。线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。然后线程等待,直到它可以重新获得监视器的所有权并继续执行。
使用格式:
5.信号灯法
用一个标志位来表示资源是否可用
没有缓冲区,所以资源最多只有一份
public class D25 {
public static void main(String[] args) {
Dish dish = new Dish();
new Cooker(dish).start();
new Customer(dish).start();
}
}
class Cooker extends Thread{
Dish dish;
Cooker(Dish dish){
this.dish = dish;
}
@Override
public void run() {
for (int i = 0; i < 15; i++) {
if(i%2==0)
dish.cook("Fired Chicken");
else
dish.cook("Beef");
}
}
}
class Customer extends Thread{
Dish dish;
Customer(Dish dish){
this.dish = dish;
}
@Override
public void run() {
for (int i = 0; i < 15; i++) {
dish.eat();
}
}
}
class Dish{
String name;
boolean flag = false;
synchronized void cook(String name){
while(flag){
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
this.name = name;
flag = !flag;
System.out.println(Thread.currentThread().getName() + " cook " + name);
notifyAll();
}
synchronized void eat(){
while(!flag){
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
flag = !flag;
System.out.println(Thread.currentThread().getName() + " eat " + name);
notifyAll();
}
}
结果:线程协作