看见有些作者在书上用synchronized同步锁去实现,利用wait()和notify()发信号。
其实锁方法是没办法并发的,这样做会把并行变成串行计算了。
信号量最好是创建一个新的类包含生产者和消费者的信号,再使用关键字volatile保证有序性。
代码如下:
public class Main {
public static void main(String[]args){
LinkedList<Integer>queen = new LinkedList<Integer>();
Sign sign = new Sign();
sign.iniSign();
new Thread(new Business(new Productor(),queen,500,100,sign)).start();
new Thread(new Business(new Customer(),queen,5,1000,sign)).start();
}
}
/**
* 信号
*/
public class Sign {
public volatile int sign_p = 0;
public volatile int sing_c = 0;
public void iniSign(){
this.sign_p = 1;
this.sing_c = 0;
}
}
public class Business implements Runnable {
Person person;
LinkedList<Integer> queen;
int len;
int time;
Sign sign;
public Business(Person person,LinkedList<Integer> queen, int len,int time,Sign sign) {
this.person = person;
this.queen = queen;
this.len = len;
this.time = time;
this.sign = sign;
}
@Override
public void run() {
person.doThis(queen,len,time,sign);
}
}
public interface Person {
void doThis(LinkedList<Integer>queen,int len,int time,Sign sign);
}
/**
* 消费者,如果队列无数据,无法消费
*/
public class Customer implements Person {
public synchronized void doThis(LinkedList queen, int len, int time, Sign sign) {
System.out.println("消费者就绪");
while (true) {
while (sign.sing_c == 0) {
}
try {
Thread.sleep(time);
} catch (InterruptedException e) {
}
if (queen.size() > 0) {
System.out.println("消费者消费数据: " + queen.removeFirst());
sign.sign_p = 1;//释放生产信号
} else {
sign.sing_c = 0; //冻结消费信号
}
}
}
}
public synchronized void doThis(LinkedList<Integer> queen, int len, int time,Sign sign) { System.out.printf("生产者就绪"); int i = 0; while (true) { while(sign.sign_p == 0){ // System.out.println("生产者阻塞!!!"); } try { Thread.sleep(time); } catch (InterruptedException e) { } if (queen.size() < len) { queen.addLast(i); System.out.println("生产者,生产数据: " + i++); sign.sing_c = 1;//释放消费信号 } else { sign.sign_p = 0; //冻结生产信号 } } } }