7.3.3消费者
让我们看看消费者的程序:classConsumerextendsThread{privateSoupsoup;
publicConsumer(Soups){//keepourowncopyofthesharedobjectsoup
=s;}
publicvoidrun(){charc;//Eat10lettersfromthealphabetsoupfor
(intI=0;i
letterthatweretrievedSystem.out.println(\"Atealetter:\"+c);//try
{sleep((int)(Math.raddom()*2000));}catch(InterruptedExceptione){}}}}
同理,象生产者一样,我们用soup.eat()来处理信息。那么,Soup类到底干什么呢?
7.3.4监视
Soup类执行监视两个线程?reg;间传输信息的功能。监视是多线程中不可缺少的一部分,因为它保持了通讯的流?copy;。让我们看看Soup.java文件:classSoup{privatecharbuffer[]=newchar[6];privateintnext=0;//Flagstokeeptrackof
ourbufferstatusprivatebooleanisFull=false;privatebooleanisEmpty
=true;publicsyschronizedchareat(){//Wecan\'teatifthereisn\'tanything
inthebufferwhile(isEmpty==true){try{wait();//we\'llexitthis
whenisEmptyturnsfalse}catch(InterruptedExceptione){}}//decrement
thecount,sincewe\'regoingtoeatoneletternext--;//Didweeatthe
lastletter?if(next==0){isEmpty=true;}//Weknowthebuffercan\'t
befull,becausewejustateisFull=false;notify();//returntheletter
tothethreadthatiseatingreturn(buffer[next]);}
//methodtoaddletterstothebufferpublicsynchronizedvoidadd(char
c){//Waitarounduntilthere\'sroomtoaddanotherletterwhile(isFull
==true){try{wait();//ThiswillexitwhenisFullturnsfalse}catch
(InterruptedExceptione){}}//addthelettertothenextavailablespot
buffer[next]=c;//Changethenextavailablespotnext++;//Arewefull;
if(next==6){isFull=true;}isEmpty=false;notify();}}soup类包含两个重要特征:数据成员buffer[]是私有的,功能成员add()和eat()是公有的。
数据私有避免了生产者和消费者直接获得数据。直接访问数据可能造成错误。例如,如果消费者企图从空缓冲区里取出数据,你将得到不必要的异常,否则,你只能锁住进程。同步访问方法避免了破坏一个共享对象。当生产者向soup里加入一个字母时,消费者不能吃字符,诸如此类。这种同步是维持共享对象完整性的重要方面。notify()函数将唤醒每一个等待线程。等待线程将继续它的访问。
7.3.5联系起来
现在我们有一个生产者,一个消费者和一个共享对象,怎样实现它们的交互呢?我们只需要一个简单的控制程序来启动所有的线程并确信每一个线程都是访问的同一个共享对象。下面是控制程序的代码,SoupTest.java:
classSoupTest{publicstaticvoidmain(Stringargs[]){Soups=new
Soup();Producerp1=newProducer(s);Consumerc1=newConsumer(s);
p1.start();c1.start();}}
7.3.6监视生产者
生产者/消费者模型程序经常用来实现远程监视功能,它让消费者看到生产者同用户的交互或同系统其它部分的交互。例如,在网络中,一组生产者线程可以在很多工作站上运行。生产者可以打印文档,文档打印后,一个标志将保存下来。一个(或多个?copy;消费者将保存标志并在晚上报告白天打印活动的情况。另外,还有例子在一个工作站是分出几个独立的窗口。一个窗口用作用户输入(生产者)另一个窗口作出对输入的反应(消费者)。
7.4线程API列表
下面是一个常用的线程类的方法函数列表:类函数:以下是Thread的静态函数,即可以直接从Thread类调用。
currentThread返回正在运行的Thread对象yield停止运行当前线程,让系统运行下一个线程sleep(intn)让当前线程睡眠n毫秒对象函数:以下函数必须用Thread的实例对象来调用。
startstart函数告诉java运行系统为本线程建立一个执行环境,然后调用本线程的run()函数。run是运行本线程的将要执行的代码,也是Runnable接口的唯一函数。当一个线程初始化后,由start函数来调用它,一?copy;run函数返回,本线程也就终止了。stop让某线程马上终止,系统将删除本线程的执行环境suspend与stop函数不同,suspend将线程暂停执行,但系统不破坏线程的执行环境,你可以用resume来恢复本线程的执行resume恢复被挂起的线程进入运行状态setPriority(intp)给线程设置优先级getPriority返回线程的优先级setName(Stringname)给线程设置名称getName取线程的名称
本章小结:
1.多线程是java语言的重要特点,java语言用Thread类封装了线程的所有操作。
2.线程的接口名为Runnable
3.线程间同步机制为synchronized关键词
4.线程间通讯靠wait与notify消息
2015年全国职称计算机考试教材(2007模 .. 定价:¥225 优惠价:¥213 更多书籍 | |
全国职称计算机考试速成过关系列套装:W .. 定价:¥133 优惠价:¥133.0 更多书籍 |