上次学习了java线程的同步,在线程的使用过程中需要注意数据的操作问题。说道这个,就会想到在学习同步时的经典示例---生产者消费者
这样,首先的看看API:
创建一个产品对象(数据),在创建一个仓库用来存放产品(自定义一个容器即可),然后就可以创建生产者和消费者了。
首先,我们想到的是可能会有两个消费者(生产者)同时使用了同一个对象操作(就貌似经典的银行存取问题了),这中情况是不允许发生的。所以,我们需要将操作锁定
其次,仓库是有量的限制的,所以,上面的方法就有用了
下面,来看看代码:
public class ProducerCustomer {
public static void main(String[] args) {
SyncStack ss = new SyncStack();
Producer pr = new Producer(ss);
Customer cr = new Customer(ss);
Thread pr1 = new Thread(pr);
Thread pr2 = new Thread(pr);
Thread cr1 = new Thread(cr);
Thread cr2 = new Thread(cr);
pr1.setName("---生产者P1");
pr2.setName("---生产者p2");
cr1.setName("消费者c1");
cr2.setName("消费者c2");
pr1.start();
pr2.start();
cr1.start();
cr2.start();
}
}
//生产消费对象
class Product{
private int id;
public Product(int id) {
this.id = id;
}
public String toString() {
return "Product的编号: " + id;
}
}
//存储产品的仓库
class SyncStack{
//索引,其大小是库存量
int index = 0;
Product[] arrPd = new Product[10];
//生产者生产
public synchronized void push(Product pd){
//如果仓库满了
while(index == arrPd.length){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
arrPd[index] = pd;
index ++;
}
//消费者消费
public synchronized Product pop(){
//仓库没有存货
while(index == 0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
return arrPd[--index];
}
}
class Producer implements Runnable{
SyncStack ss = null;
public Producer(SyncStack ss){
this.ss = ss;
}
public void run() {
for(int i = 1; i <= 10; i++){
Product pd = new Product(i);
ss.push(pd);
System.out.println(Thread.currentThread().getName()+"生产了"+pd.toString());
try {
//随机睡眠一个时间
Thread.sleep((int)Math.random()*100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Customer implements Runnable{
SyncStack ss = null;
public Customer(SyncStack ss){
this.ss = ss;
}
public void run() {
for(int i = 1; i <= 10; i++){
Product pd = ss.pop();
System.out.println(Thread.currentThread().getName()+"消费了"+pd.toString());
try {
//随机睡眠一个时间
Thread.sleep((int)Math.random()*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}