涉及线程的同步和通信
假设仓库中只存放一件产品,如果仓库中没有产品,则生产者将产品放入仓库,否则停止生产并等待,直到仓库中的产品被消费者取走为止,如果仓库中放有产品,则消费者可以将产品取走消费,否则停止消费并等待,直到仓库中再次放入产品为止。
使用 同步方法或Lock锁进行线程通信时,两者唯一不同的是商品类,其他的(消费者线程,生产者线程,测试类都是相同的)
1.同步方法下的商品类
package com.yue2.commu4;
//同步方法下的线程通信
public class Product {
private String color;
private String name;
boolean flag = false;
public Product() { }
public Product(String color, String name) {
this.color = color;
this.name = name;
}
public String getColor() {return color;}
public void setColor(String color) {this.color = color;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
@Override
public String toString() {
return "Product{" +
"color='" + color + '\'' +
", name='" + name + '\'' +
'}';
}
public synchronized void consume() {
if (!flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费者消费了一个商品 " + name + " " + color);
this.flag=false;
this.notify();
}
public synchronized void produce(int i) {
if (flag) {
try {
//this.wait();
wait();//可简写
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (i % 2 == 0) {
this.name = "馒头";
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.color = "白色";
} else {
this.name = "玉米饼";
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.color = "黄色";
}
System.out.println("生产者生产了一个商品 " + name + " " + color);
flag = true;
//this.notify();
notify();
}
}
2.Lock锁下的商品类
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//Lock下的线程通信
public class Product {
private String color;
private String name;
boolean flag = false;
private Lock lock = new ReentrantLock();
private Condition produceCondition = lock.newCondition();
private Condition consumeCondition = lock.newCondition();
public Product() {}
public Product(String color, String name) {this.color = color;this.name = name;}
public String getColor() {return color;}
public void setColor(String color) {this.color = color;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
@Override
public String toString() {
return "Product{" +
"color='" + color + '\'' +
", name='" + name + '\'' +
'}';
}
public void consume() {
lock.lock();
try {
if (!flag) {
try {
consumeCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费者消费了一个商品 " + name + " " + color);
flag = false;
produceCondition.signal();
} finally {
lock.unlock();
}
}
public void produce(int i) {
lock.lock();
try {
if (flag) {
try {
produceCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (i % 2 == 0) {
this.name = "馒头";
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.color = "白色";
} else {
this.name = "玉米饼";
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.color = "黄色";
}
System.out.println("生产者生产了一个商品 " + name + " " + color);
flag = true;
consumeCondition.signal();
} finally {
lock.unlock();
}
}
}
//以下是共同代码
生产者线程
public class ProductRunnable implements Runnable {
private Product product;
public ProductRunnable(Product product) {this.product = product;}
public void setProduct(Product product) {this.product = product;}
@Override
public void run() {
int i = 0;
while (true) {
product.produce(i);
i++;
}
}
}
消费者线程
public class ConsumeRunnable implements Runnable {
private Product product;
public ConsumeRunnable() { }
public ConsumeRunnable(Product product) {this.product = product; }
public void setProduct(Product product) { this.product = product;}
@Override
public void run() {
while (true) {
product.consume();
}
}
}
测试类
public class Test {
public static void main(String[] args) {
Product product = new Product();
Runnable runnable = new ProductRunnable(product);
Thread thread = new Thread(runnable);
thread.start();
Runnable runnable2 = new ConsumeRunnable(product);
Thread thread2 = new Thread(runnable2);
thread2.start();
}
}