欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
歡迎光臨貓小專(zhuān)區

第五章線(xiàn)程與異常處理(上)

上一章我們介紹了Java的面向對象的機制:類(lèi)、包和接口。本章我們將介紹一下Java的另外兩個(gè)機制:多線(xiàn)程(Multithread)和異常處理(Exception)。本章前半部分是關(guān)于Thread這一基本類(lèi)以及一套先進(jìn)的同步原語(yǔ)的介紹,它們使得利用Java編寫(xiě)多線(xiàn)程大為方便。在本章的后半部分我們將介紹Java的異常處理機制(Exception),異常處理機制提高了程序的健壯性。另外,本章中間將介紹一個(gè)Java的debugger工具Jdb的使用,Jdb工具對于調試多線(xiàn)程程序尤其有好處。

5.1 多線(xiàn)程(Multithread)

  5.1.1 線(xiàn)程的基本概念

在介紹多線(xiàn)程之前,我們先來(lái)了解一些相關(guān)的基本概念。一般來(lái)說(shuō),我們把程序的一次執行稱(chēng)為進(jìn)程(process)。一個(gè)進(jìn)程包括一個(gè)程序模塊和該模塊一次執行時(shí)所處理的數據。每個(gè)進(jìn)程與其它進(jìn)程擁有不同的數據塊,其內存地址是分開(kāi)的。進(jìn)程之間的通信要通過(guò)尋址,一般需使用信號、管道等進(jìn)行通信。線(xiàn)程(thread)是指進(jìn)程內部一段可獨立執行的有獨立控制流的指令序列。子線(xiàn)程與其父線(xiàn)程共享一個(gè)地址空間,同一個(gè)任務(wù)中的不同線(xiàn)程共享任務(wù)的各項資源。
多進(jìn)程與多線(xiàn)程是多任務(wù)的兩種類(lèi)型。以前的操作系統,如Win31,只運行多進(jìn)程,而Win95及WinNT則支持多線(xiàn)程與多進(jìn)程。Java通過(guò)提供Package類(lèi)(Java.lang.package)支持多進(jìn)程,而提供Thread類(lèi)來(lái)支持多線(xiàn)程。
多線(xiàn)程與多進(jìn)程的主要區別在于,線(xiàn)程是一個(gè)進(jìn)程中一段獨立的控制流,一個(gè)進(jìn)程可以擁有若干個(gè)線(xiàn)程。在多進(jìn)程設計中各個(gè)進(jìn)程之間的數據塊是相互獨立的,一般彼此不影響,要通過(guò)信號、管道等進(jìn)行交流。而在多線(xiàn)程設計中,各個(gè)線(xiàn)程不一定獨立,同一任務(wù)中的各個(gè)線(xiàn)程共享程序段、數據段等資源,如圖5.1。
正如字面上所表述的那樣,多線(xiàn)程就是同時(shí)有多個(gè)線(xiàn)程在執行。在多CPU的計算機中,多線(xiàn)程的實(shí)現是真正的物理上的同時(shí)執行。而對于單CPU的計算機而言,實(shí)現的只是邏輯上的同時(shí)執行。在每個(gè)時(shí)刻,真正執行的只有一個(gè)線(xiàn)程,由操作系統進(jìn)行線(xiàn)程管理調度,但由于CPU的速度很快,讓人感到像是多個(gè)線(xiàn)程在同時(shí)執行。
多線(xiàn)程比多進(jìn)程更方便于共享資源,而Java又提供了一套先進(jìn)的同步原語(yǔ)解決線(xiàn)程之間的同步問(wèn)題,使得多線(xiàn)程設計更易發(fā)揮作用。用Java設計動(dòng)畫(huà)以及設計多媒體應用實(shí)例時(shí)會(huì )廣泛地使用到多線(xiàn)程,在后面幾章你將看到多線(xiàn)程的巨大作用,當然,現在必須先學(xué)習一些多線(xiàn)程的基本知識,慢慢地你就體會(huì )到它的優(yōu)越性。

  5.1.2 線(xiàn)程的狀態(tài)

  如同進(jìn)程有等待、運行、就緒等狀態(tài)一樣,線(xiàn)程也有其狀態(tài)。
當一個(gè)線(xiàn)程通過(guò)new被創(chuàng )建但還未運行時(shí),稱(chēng)此線(xiàn)程處于準備狀態(tài)(new狀態(tài))。當線(xiàn)程調用了start()方法或執行run()方法后,則線(xiàn)程處于可運行狀態(tài)。若在等待與其它線(xiàn)程共享資源,則稱(chēng)線(xiàn)程處于等待狀態(tài)。線(xiàn)程的另一個(gè)狀態(tài)稱(chēng)為不可運行(notrunnable)狀態(tài),此時(shí)線(xiàn)程不僅等分享處理器資源,而且在等待某個(gè)能使它返回可運行狀態(tài)的事件,例如被方法suspend()掛起的進(jìn)程就要等待方法resume()方可被喚醒。當調用了stop()方法或線(xiàn)程執行完畢,則線(xiàn)程進(jìn)入死亡(dead)狀態(tài)。線(xiàn)程的各個(gè)狀態(tài)之間的轉換關(guān)系見(jiàn)圖5.2。

  5.1.3 創(chuàng )建線(xiàn)程

  在了解基本概念后,下面學(xué)習如何在Java中創(chuàng )建多線(xiàn)程。
Java通過(guò)java.lang.Thread類(lèi)來(lái)支持多線(xiàn)程。在Thread類(lèi)中封裝了獨立的有關(guān)線(xiàn)程執行的數據和方法,并將多線(xiàn)程與面向對象的結構合為一體。
Java提供了兩種方法創(chuàng )建線(xiàn)程,一種是繼承Thread類(lèi),另一種則是實(shí)現接口Runnable。
1.繼承Thread類(lèi)
通過(guò)繼承Thread類(lèi)創(chuàng )建線(xiàn)程十分簡(jiǎn)單,只需要重載run()方法提供執行入口就可以,下面我們通過(guò)例5.1來(lái)解釋說(shuō)明。
例5.1 ThreadTest1.java。

  1. import java.lang.Thread;
  2. import java.lang.System;
  3. import java.lang.Math;
  4. import java.lang.InterruptedException;
  5. class ThreadTest1{
  6. public static void main(String args[])
  7.   throws java.io.IOException{
  8.   System.out.println("If want to show the result,press return");
  9.   MyThread thread1=new MyThread("thread1");
  10.   MyThread thread1=new MyThread("thread2");//創(chuàng )建了兩個(gè)線(xiàn)程thread1和thread2
  11.   thread1.start();//開(kāi)始執行線(xiàn)程
  12.   thread2.start();
  13.   char ch;
  14.   while((ch=(char)System.in.read()) != ‘\n‘);//不斷循環(huán),等待輸入回車(chē)符
  15.   thread1.tStart();//改變thread1和thread2中的循環(huán)控制變量的值
  16.   thread2.tStart();//以下部分保證main()方法是最后一個(gè)結束的
  17.   while((thread1.isAlive())|(thread2.isAlive()));
  18.   /*{
  19.   you can do anything that you want to do here.
  20.   }
  21.   */
  22.   System.out.println("The test is end.");
  23. }
  24. }
  25. //類(lèi)MyThread繼承了類(lèi)Thread
  26. class MyThread extends Thread{
  27. private boolean keepRunning=true;
  28. public MyThread(String id){//類(lèi)MyThread的構造方法
  29.   super(id);
  30. }
  31. void randomWait(){//讓線(xiàn)程處于等待狀態(tài)
  32.   try{
  33.     sleep((long)(3000*Math.random()));
  34.   }
  35.   catch(InterruptedException x){
  36.     System.out.println("Interrupted!");
  37.   }
  38. }
  39. public void tStart(){
  40.   keepRunning=false;
  41. }
  42. public void run(){//重寫(xiě)了類(lèi)Thread中的方法run(),main()中調用Thread的方法start()后將自動(dòng)調用此方法
  43. int i=0;
  44. while(keepRunning) i++;//i代表循環(huán)次數
  45. //輸出結果
  46. for(int j=0;j<=3;i++){
  47.   randomWait();
  48.   System.out.println("I am"+getName()+"—— I have run"+i+"times.");
  49.   i++;
  50.   }
  51.   System.out.println(getName()+" is dead!");
  52. }
  53. }
  54.  
這個(gè)程序中創(chuàng )建了兩個(gè)線(xiàn)程thread1和trhrad2。每個(gè)線(xiàn)程將打印一些內容。當線(xiàn)程死亡時(shí),將打印出線(xiàn)程死亡信息。試著(zhù)執行一下這個(gè)程序,你將發(fā)現每次的結果都不盡相同。
運行結果:(略)
下面我們分析一下這個(gè)程序。為創(chuàng )建Thread,第一行你必須寫(xiě)importjava.lang.Thread。行6~25中書(shū)寫(xiě)的類(lèi)ThreadTest1包含了一個(gè)main()方法(行7~24)。行8的throwsjava.io.IOException暗示了main()方法中可以產(chǎn)生IOException(有關(guān)異常處理后面幾節將詳細介紹),這主要是為了調用方法System.in.read()實(shí)現輸入功能。main()方法中創(chuàng )建了兩個(gè)MyThread的對象,即行10的thread1與行11的thread2。
行28~55中書(shū)寫(xiě)的類(lèi)MyThread是Thread類(lèi)的子類(lèi)。在類(lèi)MyThread中重寫(xiě)了方法run()(行43~54)。在此種構造線(xiàn)程的方法中,這是必須的。行29~33定義了MyThread類(lèi)的構造方法MyThread(Stringid)。行32和行40定義了方法randomWait()和tStart()。
在ThreadTest1的main()方法中,當行13調用thread1.start()與thread2.start()后,線(xiàn)程thread1與thread2進(jìn)入可運行狀態(tài),分別自動(dòng)執行其run()方法,而main()方法也繼續執行,此時(shí)相當于有三個(gè)線(xiàn)程在同時(shí)執行。
看一下程序,此時(shí)thread1與thread2在執行第44~54行的run()方法,為斷循環(huán)并累計循環(huán)次數,而main()則在等待循環(huán)直至入為回車(chē)符。輸入回車(chē)符,main()方法結束循環(huán),繼續執行,調用了MyThread中方法tStart()(41~43行),這樣結束了Thread1與Thread2在run()方法中的循環(huán),開(kāi)始執行輸出。由于thread1,thread2與main()三個(gè)線(xiàn)程輪流占有CPU,所以顯示了各自結果,這也是為何多次執行結果不同的原因,此時(shí)體現了多線(xiàn)程的功能。
請注意一下Run()中調用了MyThread類(lèi)中自定義的方法randomWait()(33~40行)。在randomWait()中調用了方法sleep(),sleep()方法是Thread類(lèi)中的方法,它讓正在執行的線(xiàn)程小睡片刻,進(jìn)入不可運行狀態(tài)(notrunnable狀態(tài)),當時(shí)間到時(shí),線(xiàn)程會(huì )回復到runnable狀態(tài)。當線(xiàn)程執行sleep()時(shí),有可能會(huì )被打斷,因而程序中加了一段處理InterruptedException的中斷處理和打印信息,這樣加強了程序的健壯性。
另外,人們會(huì )注意到,在main()中有一段循環(huán)并未完成什么功能,這是為了簡(jiǎn)化程序,其實(shí)那段時(shí)間中你可以做你想完成的任何工作。但請注意,在執行時(shí),最后一個(gè)結束的必須是main()方法,而不可以是其它,否則執行結束將不返回C:提示符,這也是在程序中為何調用了isAlive()方法進(jìn)行判別的原因。調用類(lèi)Thread的isAlive()方法可以測試線(xiàn)程是否仍在運行狀態(tài)(此外指還未死亡)。
至此,你已真正了解了你的第一個(gè)關(guān)于Thread的程序,其實(shí)Thread中還有很多方法在此未被使用,后面將會(huì )進(jìn)一步介紹。下面先介紹一下創(chuàng )建Thtead的另一個(gè)方法:利用實(shí)現接口Runnable創(chuàng )建Thread。
2.實(shí)現接口Runnable
使用用類(lèi)java.lang.Runnable中的接口Runnable也可創(chuàng )建線(xiàn)程。下面的例子與例5.1實(shí)現的功能相同,只是它利用接口Runnable來(lái)實(shí)現。
例5.2 ThreadTest2.java。
  1. import java.lang.Thread;
  2. import java.lang.System;
  3. import java.lang.Math;
  4. import java.lang.InterruptedException;
  5. import java.lang.Runnable;
  6. class ThreadTest2{
  7. public static void main(String args[])
  8.   throws java.io.IOException{
  9.   System.out.println("If want to show the result,press return");//創(chuàng )建了兩個(gè)MyClass類(lèi)的對象//class1和class2,MyClass類(lèi)實(shí)現了接口Runnable
  10.   MyClass class1 = new MyClass("thread1");
  11.   MyClass class2 = new MyClass("thread2");//創(chuàng )建了兩個(gè)MyClass類(lèi)的對象class1和class2,MyClass類(lèi)實(shí)現了接口Runnable
  12.   Thread thread1=new Thread(class1);
  13.   Thread thread2=new Thread(class2);//將對象class1和class2作為參數傳給Thread類(lèi)的構造函數,創(chuàng )建了兩個(gè)線(xiàn)程thread1和thread2。
  14.   thread1.start();//開(kāi)始執行線(xiàn)程
  15.   thread2.start();
  16.   char ch;
  17.   while((ch=(char)System.in.read()) != ‘\n‘);//不斷循環(huán),等待輸入回車(chē)符
  18.   class1.tStart();//改變thread1和thread2中的循環(huán)控制變量的值
  19.   class2.tStart();//以下部分保證main()方法是最后一個(gè)結束的
  20.   while((thread1.isAlive())||(thread2.isAlive()));
  21.   /*{
  22.   you can do anything that you want to do here.
  23.   }
  24.   */
  25.   System.out.println("The test is end.");
  26. }
  27. }
  28. //類(lèi)MyClass實(shí)現了接口Runnable
  29. class MyClass implements Runnable{
  30. boolean keepRunning=true;
  31. String name;
  32. public MyClass(String id){//類(lèi)MyClass的構造方法
  33.   name=id;
  34. }
  35. void randomWait(){//讓線(xiàn)程處于等待狀態(tài)
  36.   try{
  37. Thread.currentThread().sleep((long)(3000*Math.random()));//注意:接口 Runnable中沒(méi)有方法sleep(),所以必須先調用Thread的類(lèi)方法currentThread()來(lái)獲取一個(gè)Thread的對象,然后再調 用方法seleep()
  38.   }
  39.   catch(InterruptedException x){
  40.     System.out.println("Interrupted!");
  41.   }
  42. }
  43. public void tStart(){
  44.   keepRunning=false;
  45. }
  46. public void run(){//與程序ThreadTest1.java類(lèi)似
  47. int i=0;
  48. while(keepRunning) i++;//i代表循環(huán)次數
  49. //輸出結果
  50. for(int j=0;j<=3;j++){
  51.   randomWait();
  52.   System.out.println("I am "+name+"—— I have run "+i+" times.");
  53.   i++;
  54.   }
  55.   System.out.println(name+" is dead!");
  56. }
  57. }
  58.  

 

 

  運行結果:(略)
ThreadTest2創(chuàng )建thread1與thread2的方法(11~14行)與ThreadTest1不同,ThreadTest2直接創(chuàng )建了一個(gè)Thread的對象,并將Myclass的對象作為參數傳給Thread的構造方法。任何實(shí)現了Runnable接口的類(lèi)的對象都可以作Thread構造方法的參數。在main()方法中,其余部分程序ThreadTest2與ThreadTest1.java相同。
ThreadTest2的MyClass類(lèi)(31~59行)實(shí)現了接口Runnable,注意MyClass的構造方法實(shí)現了name這一類(lèi)變量,實(shí)現run()時(shí)不需要調用Thread的方法getName(),但在實(shí)現randomWait()時(shí)要使用Thread.currentThread().Sleep()(39行),因為Runnable接口并未提供方法sleep(),因而實(shí)現時(shí)必須調用Thread的類(lèi)方法currentThread()來(lái)調用sleep()。
事實(shí)上,無(wú)論用繼承Thread的方法或用實(shí)現接口Runnable的方法來(lái)實(shí)現多線(xiàn)程,在程序書(shū)寫(xiě)時(shí)區別不大,只需概念清楚略加注意便可。使用繼承Thread類(lèi)的方法比較簡(jiǎn)單易懂,實(shí)現方便。但如果你創(chuàng )建的Thread需要是某個(gè)其它類(lèi)的子類(lèi)時(shí),使用繼承Thread的方法就會(huì )出麻煩。比如,實(shí)現Applet時(shí),每個(gè)applet必須是java.applet.Applet的子類(lèi),此時(shí)想要實(shí)現多線(xiàn)程,只有通過(guò)使用Runnable接口,當然,使用Runnable接口來(lái)實(shí)現線(xiàn)程,在書(shū)寫(xiě)時(shí)會(huì )比較麻煩,因為你將不得不多做一些工作才可調用Thread的方法。
3.線(xiàn)程同步
在使用多線(xiàn)程時(shí),由于可以共享資源,有時(shí)就會(huì )發(fā)生沖突。舉一個(gè)簡(jiǎn)單的例子,有兩個(gè)線(xiàn)程thread1負責寫(xiě),thread2負責讀,當它們操作同一個(gè)對象時(shí),會(huì )發(fā)現由于thread1與thread2是同時(shí)執行的,因此可能thread1修改了數據而thread2讀出的仍為舊數據,此時(shí)用戶(hù)將無(wú)法獲得預期的結果。問(wèn)題之所以產(chǎn)生主要是由于資源使用協(xié)調不當(不同步)造成的。以前,這個(gè)問(wèn)題一般由操作系統解決,而Java提供了自己協(xié)調資源的方法。
Java提供了同步方法和同步狀態(tài)來(lái)協(xié)調資源。Java規定:被宣布為同步(使用Synchronized關(guān)鍵字)的方法,對象或類(lèi)數據,在任何一個(gè)時(shí)刻只能被一個(gè)線(xiàn)程使用。通過(guò)這種方式使資源合理使用,達到線(xiàn)程同步的目的。
我們將程序5.1的類(lèi)MyThread中的方法run()改成如下所示(見(jiàn)程序片段5.3),并加入一個(gè)類(lèi)SynchronizedShow實(shí)現同步,大家可以運行看到執行結果:每次執行Show()的只有一個(gè)線(xiàn)程。
例5.3 ThreadTest3.java片段
public void run(){
int i=0;
while(keepRunning) i++;//i代表循環(huán)次數
//輸出結果
SynchronizedShow.show(getName(),i);
SynchronizedShow.println(getName()+"isdead!");
}
class SychronizedShow{
//方法show(String,int)被宣布為同步的方法,因此每次只有一個(gè)線(xiàn)程能調用這個(gè)方法
public static synchronized voidshow(String,name,int i){
int k;
k=i;
for(intj=0;j<=3;j++){
MyThread t=(Mythread)Thread.currentThread();
t.randomWait();
System.out.println("Iam"+name+"—— I haverun"+k+" times.");
k++;
}
}
}
運行結果(略)
另外,利用Synchronized可以鎖定對象。
例如:Synchronized(某個(gè)對象A){
//程序塊
}
在此程序塊中,對于相同的對象A,在任何時(shí)候只可以有一個(gè)線(xiàn)程在此代碼中執行,但對于不同的對象還是有很多個(gè)線(xiàn)程同時(shí)執行的。用同樣的方法也可以協(xié)調類(lèi)數據,例如:
Synchroinzed(new欲鎖定的類(lèi)().getmethod()){
//程序塊
}
方法getmethod()是用來(lái)獲取類(lèi)數據的,這樣通過(guò)利用Synchronized這一關(guān)鍵字,我們可以自由協(xié)調對象實(shí)體的各種數據。
除了簡(jiǎn)單使用Synchronized這一關(guān)鍵字外,Java有一套復雜的同步機制,其基本原理采用了C.A.R.Hoare提出的,并已被廣泛使用的監視規則和條件變量規則。在Java中,所有的類(lèi)與對象都和管程(monitor)聯(lián)系在一起。當一個(gè)對象獲得管程(monitor)時(shí),它就可以執行同步方法,直至它讓出管程(monitor),其它對象方可進(jìn)入同步方法。當一個(gè)方法被完成時(shí),它將自動(dòng)讓管理(monitor),另外執行某些方法例如wait(),suspend()等時(shí)也會(huì )讓出管程(monitor)。
讀者可以試著(zhù)將例5.1的main()方法改成以下形式(風(fēng)險5.4)執行一下。人們會(huì )發(fā)現與前面利用Synchronized的結果類(lèi)似,原因是thread1執行suspend()后被掛起直至resume()方被喚醒。因此用這種方法也可以實(shí)現同步。
例5.4 Thread Test4.java的程序片斷。
public static void main(String args[])
throws java.io.IOException{
System.out.println("If want toshow the result,press return");
MyThread thread1=newMyThread("thread1");
MyThread thread2=newMyThread("thread2");
thread1.start();
thread2.start();
char ch;
while((ch=(char)System.in.read())!=‘\n‘);
thread1.tStart();
//將線(xiàn)程thread1掛起
thread1.suspend();
thread2.tStart();
while(thread2.isAlive());
//線(xiàn)程thread2進(jìn)入死亡狀態(tài)后,釋放線(xiàn)程thread1
thread1.resume();
while(thread1.isAlive());
/*{
you can do anything that youwant to do here.
}
*/
System.out.println("The testis end.");
}
運行結果:(略)
4.進(jìn)一步學(xué)習
上幾節我們學(xué)習了定義Thread的兩種方法,線(xiàn)程的同步的基本知識。在本節中我們將進(jìn)一步給出有關(guān)線(xiàn)程的一些更詳細的內容。
(1)若干常用的方法
首先,我們給出一些Thread類(lèi)中最常用的方法供大學(xué)參考。
■currentThread()
這是一個(gè)類(lèi)方法,返回當前正在執行的線(xiàn)程。
■isAlive()
判別一個(gè)線(xiàn)程是否仍然活著(zhù),包括這個(gè)線(xiàn)程正在執行或有機會(huì )被執行。返回一個(gè)布爾值。
■suspend()
懸掛起某個(gè)線(xiàn)程,并使得這個(gè)線(xiàn)程只可被resume()方法激活。
■resume()
與suspend()配合使用。喚醒線(xiàn)程。
■yeild()
強迫線(xiàn)程交出執行權利供其它線(xiàn)程使用。
■stop()
使線(xiàn)程進(jìn)入死亡(dead)狀態(tài)。
這些方法是線(xiàn)程中最常被使用到的方法,若要詳細了解更多的內容可以查閱Java的API。
(2)線(xiàn)程優(yōu)先級與調度
由于我我們一般使用的計算機是單CPU的,所以在執行多線(xiàn)程程序時(shí)需進(jìn)行線(xiàn)程調度。線(xiàn)程調度是由線(xiàn)程的優(yōu)先級決定的。高優(yōu)先級的線(xiàn)程總是先運行的。Java采用的是搶占式(preemptive)的調度方式,即當高優(yōu)先級的線(xiàn)程進(jìn)入可運行(runnable)狀態(tài)時(shí),會(huì )搶占低優(yōu)先級的線(xiàn)程的位置,并開(kāi)始執行。當同時(shí)有兩個(gè)或兩個(gè)以上的線(xiàn)程具有高優(yōu)先級并進(jìn)入可運行狀態(tài),Java的調度會(huì )自動(dòng)在這些線(xiàn)程間交替調度執行。
在Java中,Thread類(lèi)中預定義了三個(gè)常量:
MAX_PRIORITY,MIN_PRIORITY,NORM_PRIORITY,
一個(gè)線(xiàn)程的優(yōu)先級應在MAX_PRIORITY與MIN_PRIORITY之間。NORM_PRIORITY是缺省的優(yōu)先級值,一般是MIN_PRIORITY與MAX_PRIORITY的平均值。
在Java中,Thread類(lèi)提供了方法設置和獲取優(yōu)先級。
setPriority(int)  用于設置線(xiàn)程的優(yōu)先數
setPriority()   用于獲取線(xiàn)程的優(yōu)先數
(3)線(xiàn)程組(Thread Group)
線(xiàn)程組是包括了許多線(xiàn)程的對象集。每個(gè)線(xiàn)程有自己特定的線(xiàn)程組。一個(gè)線(xiàn)程在創(chuàng )建時(shí)就屬于某個(gè)線(xiàn)程組,直至其執行結束,此線(xiàn)程不可更改其所屬的線(xiàn)程組。Thread類(lèi)中提供了構造方法使創(chuàng )建線(xiàn)程時(shí)同時(shí)決定其線(xiàn)程組。Thread類(lèi)總共提供了六種構造方法:
Thread();
Thread(String);
Thread(Runnable);
Thread(Runnable,String);
Thread(ThreadGroup,String);
Thread(ThreadGroup,Runnable,String);
前四種缺省了線(xiàn)程組,表示所創(chuàng )建的線(xiàn)程屬于main線(xiàn)程組,后兩種則指定了所創(chuàng )建的線(xiàn)程的線(xiàn)程組。線(xiàn)程可以訪(fǎng)問(wèn)自己所在的線(xiàn)程組,但不能訪(fǎng)問(wèn)本線(xiàn)程組的父類(lèi)。對線(xiàn)程組進(jìn)行操作就是對線(xiàn)程組中的各個(gè)線(xiàn)程同時(shí)進(jìn)行操作。
線(xiàn)程組的構造方法:
ThreadGroup(String groupName)
創(chuàng )建名為groupName的線(xiàn)程組,該線(xiàn)程組的父類(lèi)為當前線(xiàn)程所在程組。
ThreadGroup(ThreadGroup parent,StringgroupName)
創(chuàng )建名為groupName的線(xiàn)程組,該線(xiàn)程組的父類(lèi)是parent。
(4)wait()和notify()方法
Java在類(lèi)java.lang.Object中定義了wait()和notify()方法,調用它們也可以實(shí)現線(xiàn)程之間的同步。
■public final void wait(longmillseconds) throws InterruptedException
調用此方法時(shí),被調對象進(jìn)入等待狀態(tài),直到被喚醒或等待時(shí)間到。
■public final void notify()
喚醒一個(gè)對象內處于等待狀態(tài)的對象。
■public find void Allotify()
喚醒一個(gè)對象內所有處于等待狀態(tài)的對象。

5.2 Debugger的使用

  至此我們已經(jīng)書(shū)寫(xiě)了不少程序,大家可能發(fā)覺(jué)出錯要調試很困難,其實(shí)java工具包中的Javadebugger為用戶(hù)提供了方便的調試機制。雖然jdb的界面不是很漂亮,但很有用,尤其對于調試多線(xiàn)程程序。
Java的debugger需要jdb命令激活。如下執行:
C:\>jdb
在執行之前,請用帶-g參數的javac對程序進(jìn)行編譯,本節我們使用了前一章中check.java,第一步先重新編譯方法如下:
C:\synetjava\java\exmples>javac -gcheck.java
用下面的方法可以進(jìn)入jdb,可以直接在jdb后緊接要調試的類(lèi)名,也可缺省,在進(jìn)入jdb后利用load載入要調試的類(lèi)。
C:\MyDemo\dawn>jdb Check
Initializing jdb...
0xe8d370:class(Check)
在Check這一類(lèi)名前的16進(jìn)制數是Check類(lèi)在Java運行時(shí)的標識。
進(jìn)入了jdb后,可以使用help來(lái)獲取所需的使用信息:
> help
** command list **
run [class [args]]     --start execution of application‘s main class

  threads [threadgroup]   --list threads
thread <thread id>     --set default thread
suspend [thread id(s)]   --suspend threads (default: all)
resume [thread id(s)]   --resume threads (default: all)
where [thread id] | all  -- dump athread‘s stack
wherei [thread id] | all -- dump athread‘s stack, with pc info
up [n frames]       --move up a thread‘s stack
down [n frames]      --move down a thread‘s stack
kill <thread> <expr>   --kill a thread with the given exceptionobject
interrupt <thread>    --interrupt a thread

  print <expr>       --print value of expression
dump <expr>        --print all object information
eval <expr>        --evaluate expression (same as print)
set <lvalue> = <expr>   --assign new value to field/variable/arrayelement
locals           --print all local variables in current stackframe

  classes          --list currently known classes
class <class id>     --show details of named class
methods <class id>    --list a class‘s methods
fields <class id>    --list a class‘s fields

  threadgroups       --list threadgroups
threadgroup <name>    --set current threadgroup

  stop in <classid>.<method>[(argument_type,...)]
--set a breakpoint in a method
stop at <class id>:<line>-- set a breakpoint at a line
clear <classid>.<method>[(argument_type,...)]
--clear a breakpoint in a method
clear <class id>:<line> --clear a breakpoint at a line
clear          --list breakpoints
catch <class id>    --break when specified exception thrown
ignore <class id>    --cancel ‘catch‘ for the specified exception
watch [access|all] <classid>.<field name>
--watch access/modifications to a field
unwatch [access|all] <classid>.<field name>
--discontinue watching access/modifications toa field
trace methods [thread] -- trace methodentry and exit
untrace methods [thread] -- stoptracing method entry and exit
step           --execute current line
step up         --execute until the current method returns toits cal
ler
stepi          --execute current instruction
next           --step one line (step OVER calls)
cont           --continue execution from breakpoint

  list [line number|method] -- printsource code
use (or sourcepath) [source file path]
--display or change the source path
exclude [class id ... |"none"]
--do not report step or method events forspecified classes
classpath -- print classpath info fromtarget VM

  monitor <command>   --execute command each time the program stops
monitor        -- listmonitors
unmonitor <monitor#>  --delete a monitor
read <filename>    --read and execute a command file

  lock <expr>      --print lock info for an object
threadlocks [thread id] -- print lockinfo for a thread

  disablegc <expr>    --prevent garbage collection of an object
enablegc <expr>     --permit garbage collection of an object

  !!            --repeat last command
<n> <command>      --repeat command n times
help (or ?)       --list commands
version         --print version information
exit (or quit)      --exit debugger

  <class id>: full class namewith package qualifiers or a
pattern with a leading or trailingwildcard (‘*‘).
<thread id>: thread number asreported in the ‘threads‘ command
<expr>: a Java(tm) ProgrammingLanguage expression.
Most common syntax is supported.

  Startup commands can be placed ineither "jdb.ini" or".jdbrc"
in user.home or user.dir
>
利用命令stop in <classid>.<method>可以在方法中設置斷點(diǎn),用命令run運行方法。
>stop in Check.main
Breakpoint set Check.main
>run Check
running...
main[1]
Breakpoint hit: Check.main(Chech:18)
main[1] list
14   }
15  }
16  class Check{
17   public static voidmain(String args[]]){
18  =>  Son s=new Son();
19     s.speak();
20   }
21   }
main[1]
=>所指的地方即為斷點(diǎn)處,然后使用step命令進(jìn)行步調執行,結果提示斷點(diǎn)設置到了類(lèi)son中用list顯示,就可以清楚地看到斷點(diǎn)所在位置。
main[1]step
main[1]
Breakpoint hit:Son.<init>(Son:9)
main[1]list
5    void speak(String s){
6      System.out.println("Ilike "+s+".");
7    }
8   }
9   =>class Son extendsFather{
10   void speak(){
11      System.out.println("Myfather sys:");
12      super.speak();
13      super.speak("hunting");
用cont命令可以繼續執行下去,本例十分簡(jiǎn)單,所以立即給出了運行結果。我們還可以試一試help中顯示的其它命令,methodscheck顯示了check類(lèi)中定義的方法,memory顯示了java運行時(shí)刻提供的內存等等,用戶(hù)可以自己去試用一下。
main[1]cont
My father syas:main[1]
I am Father.
I like hunting.
//顯示check類(lèi)中定義的方法
main[1]methods Check
void main(String[])
void <init>()
//顯示java運行時(shí)刻提供的內存main[1]memory
Free:295928,total:1777656
//列出線(xiàn)程組
main[1]threadgrouts
1.(java.lang.ThreadGroup)0xe600b8system
2.(java.lang.ThreadGroup)0xe655e0 main
3.(java.lang.ThreadGroup)0xe8ddd8Check.main
//列出指定線(xiàn)程組中的線(xiàn)程
main[1]threads system
Group system:
1.(java.lang.Thread)0xe600d0  Frinalizertherad suspended
2.(java.lang.Thread)0xe65570  Debuggeragent running
3.(sun.tools.debug.BreakpointHandler)0xe8b080Breakpoint handler cond. waitin
Group main:
4.(java.lang.Thread)0xe600a8 mainsuspended
Group Check.main:
事實(shí)上,Jdb工具現在還存在不少缺陷正待改進(jìn),使用時(shí)有時(shí)會(huì )出現一些莫名其妙的錯誤,所以使用時(shí)請大家最好聯(lián)網(wǎng),便于查詢(xún)。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
多線(xiàn)程/JAVA多線(xiàn)程 - 魔樂(lè )培訓 高端JAVA培訓 魔樂(lè )科技JAVA培訓
Java筆記(六 程序、進(jìn)程和線(xiàn)程)
Java 多線(xiàn)程的三種實(shí)現方法
多線(xiàn)程編程
Java并發(fā)編程之線(xiàn)程的創(chuàng )建
Java 多線(xiàn)程(四) 多線(xiàn)程訪(fǎng)問(wèn)成員變量與局部變量
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久