按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
try{offScrImage=createImage(maxWidth;maxHeight);offScrGC=
offScrImage。getGraphics();offScrGC。setColor(Color。lightGray);
offScrGC。fillRect(0;0;maxWidth;maxHeight);
resize(maxWidth;maxHeight);}catch(Exceptione)
{e。printStackTrace();}
//loadtheanimationimagesintoanarrayfor(inti=0;i=images。length){index=0;}}
//Delayheresoanimationlooksnormaltry{animator。sleep(200);}catch
(InterruptedExceptione){}//Drawthenextframerepaint();}}}
7。3多线程间的通讯
7。3。1生产者和消费者
多线程的一个重要特点是它们?reg;间可以互相通讯。你可以设计线程使用公用对象,每个线程都可以独立操作公用对象。典型的线程间通讯建立在生产者和消费者模型上:一个线程产生输出;另一个线程使用输入buffer
让我们创建一个简单的”AlphabetSoup”生产者和相应的消费者。
7。3。2生产者
生产者将从thread类里派生:classProducerextendsThread
{privateSoupsoup;privateStringalphabet=”
ABCDEFGHIJKLMNOPQRSTUVWXYZ”;
publicProducer(Soups){//Keepourowncopyofthesharedobjectsoup
=s;}
publicvoidrun(){charc;//Throw10lettersintothesoupfor(int
i=0;ijavaMultiCatcha=0divby0:java。lang。arithmeticexception:/by
zeroC:》javaMutiCatch1a=1arrayindexoob:
java。lang。ArrayIndexOutOfBoundsException:42
8。6try语句的嵌套
你可以在一个成员函数调用的外面写一个try语句,在这个成员函数内部,写另一个try语句保护其他代码。每当遇到一个try语句,”异常”的框架就放到堆栈上面,直到所有的try语句都完成。如果下一级的try语句没有对某种”异常”进行处理,堆栈就会展开,直到遇到有处理这种”异常”的try语句。下面是一个try语句嵌套的例子。
classMultiNest{staticvoidprocedure(){try{intc''={1}:c'42'
=99;}catch(ArrayIndexOutOfBoundsexceptione)
{System。out。println(”arrayindexoob:”+e);}}publicstaticvoid
main(Stringargs''){try{inta=args。length;system。out。println(”a
=”+a);intb=42/a;procedure();}catch(arithmeticExceptione)
{System。out。println(”divby0:”+e);}}}
成员函数procedure里有自己的try/catch控制,所以main不用去处理ArrayIndexOutOfBoundsException。
8。7throw语句
throw语句用来明确地抛出一个”异常”。首先,你必须得到一个Throwable的实例的控制柄,通过参数传到catch子句,或者用new操作符来创建一个。下面是throw语句的通常形式。
throwThrowableInstance;
程序会在throw语句后立即终止,它后面的语句执行不到,然后在包含它的所有try块中从里向外寻找含有与其匹配的catch子句的try块。下面是一个含有throw语句的例子。
classThrowDemo{staticvoiddemoproc(){try{thrownewNullPointerException(”de3mo”);}catch(NullPointerExceptione){System。out。println(”caughtinsidedemoproc”);throwe;}}publicstaticvoidmain(Stringargs''){try{demoproc();}
catch(NullPointerExceptione){system。out。println(”recaught:”+e);}}}
8。8throws语句
throws用来标明一个成员函数可能抛出的各种”异常”。对大多数Exception子类来说,Java编译器会强迫你声明在一个成员函数中抛出的”异常”的类型。如果”异常”的类型是Error或RuntimeException,或它们的子类,这个规则不起作用,因为这?copy;在程序的正常部分中是不期待出现的。如果你想明确地抛出一个RuntimeException,你必须用throws语句来声明它的类型。这就重新定义了成员函数
的定义语法:typemethod…name(arg…list)throwsexception…list{}
下面是一段程序,它抛出了一个”异常”,但既没有捕捉它,也没有用throws来声明。这在编译时将不会通过。
classThrowsDemo1{staticvoidprocedure()'System。out。println(”inside
procedure”);thrownewIllegalAccessException(”demo”);}publicstatic
voidmain(Stringargs''){procedure();}}
为了让这个例子编译过去,我们需要声明成员函数procedure抛出了IllegalAccessException,并且在调用它的成员函数main里捕捉它。下面是正确的例子:
classThrowsDemo{staticvoidprocedure()throwsIllegalAccessException
{System。out。println(”insideprocedure”);thrownew
IllegalAccessException(”demo”);}publicstaticvoidmain(Stringargs'')
{try{procedure();}catch(IllegalAccessExceptione)
{System。out。println(”caught”+e);}}}
下面是输出结果:
C:》javaThrowsDemoinsideprocedurecaught
java。lang。IllegalAccessException:demo
8。9finally
当一个”异常”被抛出时,程序的执行就不再是线性的,跳过某?copy;行,甚至会由于没有与?reg;匹配的catch子句而过早地返回。有时确保一段代码不管发生什么”异常”都被执行到是必要的,关键词finally就是用来标识这样一段代码的。即使你没有catch子句,finally程序块也会在执行try程序块后的程序?reg;前执行。每个try语句都需要至少一个与?reg;相配的catch子句或finally子句。一个成员函数返回到调用它的成员函数,或者通过一个没捕捉到的”异常”,或者通过一个明确的return语句,finally子句总是恰好在成员函数返回前执行。下面是一个例子,它有几个成员函数,每个成员函数用不同的途径退出,但执行了finally子句。
classFinallyDemo{staticvoidprocA(){try
{System。out。println(”insideprocA”);thrownew
RuntimeException(”demo”);}finally{System。out。println(”procA's
finally”);}}staticvoidprocB(){try{System。out。println(”inside
procB”);return;}finally{System。out。println(”procB'sfinally”);}}
publicstaticvoidmain(Stringargs''){try{procA();}catch(Exception
e);procB();}}
下面是这个例子的运行结果:
C:》javaFinallyDemoi