importjava.util.Queue;publicclassConsumer<T>{privateQueue<T> tasks;publicConsumer(Queue<T> tasks){this.tasks = tasks;}publicTconsume()throwsInterruptedException{synchronized(tasks){// TODO 如果不用while,用if,会怎么样?while(tasks.size()==0){System.out.println("消费者线程进入等待:"+Thread.currentThread().getName());// >> TODO wait方法会释放monitor
tasks.wait();}T ret = tasks.poll();// >> TODO 调用notify或者notifyAll的时候,必须已经获得对象的monitor,也就是在对象的synchronized块中
tasks.notifyAll();return ret;}}}
三、执行类,Main方法
importjava.util.LinkedList;importjava.util.Queue;importjava.util.concurrent.TimeUnit;publicclassProducerConsumerAppMain{publicstaticfinalObject LOCKER =newObject();publicstaticvoidmain(String[] args){Queue<String> urls =newLinkedList<>();Consumer<String> consumer =newConsumer<>(urls);Producer<String> producer =newProducer<>(urls,1024);for(int i =0; i <100; i++){Thread consumerThread =newThread(()->{while(true){try{String url = consumer.consume();processURL(url);}catch(InterruptedException e){
e.printStackTrace();}}},"消费者-"+ i);
consumerThread.start();}for(int i =0; i <3; i++){Thread producerThread =newThread(()->{while(true){try{String url =produceURL();
producer.produce(url);}catch(InterruptedException e){
e.printStackTrace();}}},"生产者-"+ i);
producerThread.start();}}privatestaticStringproduceURL(){StringBuilder ret =newStringBuilder();
ret.append("www.");for(int i =0; i <6; i++){int rand =((int)(Math.random()*1000))%26;char ch =(char)(rand +'a');
ret.append(ch);}
ret.append(".com");return ret.toString();}privatestaticvoidprocessURL(String url)throwsInterruptedException{System.out.println("开始处理:"+ url);Thread.sleep(TimeUnit.SECONDS.toMillis(1));System.out.println("处理完成:"+ url);}}