java同步经典问题生产者消费者

时间:2021-08-12 23:53:06

生产者和消费者是一个经典的操作系统问题,涉及到多线程和信号量问题。JAVA使用同步机制和多线程机制实现这个程序设计。

在java中主要有提供两种实现线程的方法,分别为继承java.lang.Thread类和实现java.util.Runnable接口。建议大家使用后者,

因为java中的类的继承数量最多为一个,使用接口时,此类就可以继承别的类了。

同步也是两种实现方法,

一、sychronized直接在方法前添加;

二、sychronized通过synchronized(this){}实现


代码如下:

public class ProducerConsumer {
public static void main(String args[]){
SyncStack stack = new SyncStack();
Runnable p=new Producer(stack);
Runnable c = new Consumer(stack);
Thread t1 = new Thread(p);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}


class SyncStack{ //支持多线程同步操作的堆栈的实现
private int index = 0;
private char []data = new char[6];
public synchronized void push(char c){
if(index == data.length){
try{
this.wait();
}catch(InterruptedException e){}
}
this.notify();
data[index] = c;
index++;
}
public synchronized char pop(){
if(index ==0){
try{
this.wait();
}catch(InterruptedException e){}
}
this.notify();
index--;
return data[index];
}
}


class Producer implements Runnable{
SyncStack stack;
public Producer(SyncStack s){
stack = s;
}
public void run(){
for(int i=0; i<20; i++){
char c =(char)(Math.random()*26+'A');
stack.push(c);
System.out.println("produced:"+c);
try{
Thread.sleep((int)(Math.random()*1000));
}catch(InterruptedException e){
}
}
}
}


class Consumer implements Runnable{
SyncStack stack;
public Consumer(SyncStack s){
stack = s;
}
public void run(){
for(int i=0;i<20;i++){
char c = stack.pop();
System.out.println("消费:"+c);
try{
Thread.sleep((int)(Math.random()*1000));
}catch(InterruptedException e){
}
}
}
}

代码中定义了一个SyncStack类,此类是存放产品的缓冲buffer。类中定义了两个方法,push和pop,并且用synchronized修饰确保方法的互斥执行。

this.wait()和this.sleep()的区别是sleep是休眠一定时间后,自动唤醒。但是wait休眠后必须使用notify和notifyall方法才能唤醒。