My Opera is closing 3rd of March

^_^ Recycle Bin To Bienden862003 ^_^

Hãy cùng anh chia sẽ vui buồn !!!!!

Kỹ Thuật Xữ Lý Thread Và Exception Trong Java


Đề tài : Cơ chế hoạt động của tuyến đoạn và biệt lệ trong JavaA. Tuyến đoạn.(Thread)

1. Tuyến đoạn là gì?
a. Khái niệm:
b. Chu kì sống của một tuyến đoạn:
2. Đa tuyến đoạn(multithread).
a. Đa nhiệm(Multitasking)
b. Đa tuyến đoạn (multithreading).
3. Tại sao phải sử dụng đa tuyến đoạn?
4. Hai cách thiết lập tuyến đoạn.
4.1 Lớp Thread
4.2 Tuỳ chỉnh phương thức run() của lớp Thread.
a.Thiết lập tuyến đoạn bằng cách thừa kế từ lớp Thread.
b.Thiết lập tuyến đoạn bằng cách thi công giao diên Runnable.
c. Sử dụng phương pháp thiết lập nào?:
5.Thứ tự ưu tiên trong sự thực thi các tuyến đoạn

B.Phần biệt lệ (exception)

1/Giới thiệu sơ lượt về biệt lệ trong Java
2/Tìm hiểu về các khái niệm và các phương thức dùng trong việc xử lý biệt lệ
2.a. Thế nào là biệt lệ ?
2.b. Nguyên nhân gây ra biệt lệ
2.c. Mô hình xử lý biệt lệ
2.d. Giải thích công dụng của các từ khoá trong biệt lệ
3/ Các kiểu biệt lệ
3.a. Biệt lệ có sẵn
3.b. Biệt lệ tự tao.
4/ Cơ chế xử lý biệt lệ
4.a. Các cở sở xử lý biệt lệ
4.b. Ném và bắt biệt lệ thông thường
4.c. Thứ tự các khối biệt lệ
4.d. Lây lan biệt lệ
4.e. Biệt lệ lồng
5/ Thuận lợi của việc sử dụng biệt lệ

C. Ví dụ minh hoạ xử lý các loại biệt lệ trong tuyến đoạn


Lời giới thiệu
Tuyến đoạn và biệt lệ , hai khái niệm này tuy độc lập với nhau nhưng đều là những thành tố cơ bản, thường đi liền với nhau như hình với bóng. Chúng là những giải pháp và phương tiện hết sức thú vị và hữu ích. Khái niệm tuyến đoạn và biệt lệ không phải là "đặc sản" của Java nhưng việc vận dụng hai khái niệm dường như phức tạp này khi lập trình Java lại rất đơn giản. Tuyến đoạn thuộc về bản thân Java, là một phần của Java ngay từ trong "trứng nước", chứ không phải là yếu tố "ngoại lai " như trương hợp các ngôn ngữ khác. Người lập trình Java trên mọi hệ thống có thể hoàn toàn yên tâm khi sử dụng tuyến đoạn.

Như mọi thứ khác trong Java, tuyến đoạn và biệt lệ xuất hiện dưới dạng những đối tượng . Để cho tiện, ta không gọi rườm rà " đối tượng tuyến đoạn" và "đối tượng biệt lệ" mà chỉ nói ngắn gọn là "tuyến đoạn" và "biệt lệ".

A. Tuyến đoạn.(Thread)

1. Tuyến đoạn là gì?
a. Khái niệm:

Nhiều người lâp trình đều quen thuộc với việc viết những chương trình liên tục.Các chương trình như: hiển thị "Hello Word" , sắp xếp một danh sách các tên hoặc tính toán một dãy các số nguyên tố. Đó là những chương trình tuần tự. Tức là, mỗi chương trình đều có một sự bắt đầu, một sự thực thi tuần tự, và một sư kết thúc.
Một tuyến đoạn thì tương tự như những chương trình tuần tự vừa mới được mô tả . Một tuyến đoạn đơn cũng có một sự bắt đầu, trình tự, và phần cuối. Tuy nhiên, bản thân một tuyến đoạn không phải là một chương trình, nó không thể tự ý chạy, nó chỉ có thể chạy bên trong một chương trình.

Hình sau cho thấy mối quan hệ này.
Định nghĩa:
Tuyến đoạn đơn là một dòng liên tục đơn điều khiển bên trong một chương trình

Những chương trình đơn tuyến đoạn chứa những câu lệnh mà thi hành trong một tuần tự rất nhanh, nhưng chỉ một câu lệnh là thi hành tại một thơì điểm. Khi một máy tính chứa một CPU, nó chỉ có thể thi hành một chỉ lệnh máy tại một thời điểm. Khi bạn sử dụng một máy tính với nhiều CPU, máy tính đó có thể thi hành nhiều chỉ dẫn máy cùng lúc.

b. Chu kì sống của một tuyến đoạn:
Sơ đồ dưới đây cho thấy các trạng thái mà một tuyến đoạn Java có thể tồn tại trong suốt đời sống của nó. Đồng thời, nó cũng minh hoạ các phương thức gọi gây ra sự chuyển tiếp đến trạng thái khác

Một tuyến đoạn có thể tồn tại một trong các trạng thái sau trong suốt chu kì sống của nó: new, ready, running, inactive( not runnable), or finished.
Khi ban tạo ra một tuyến đoạn, nó đang tồn tại trong trạng thái new; nó đơn thuần là một đối tượng Thread trống, chưa có tài nguyên hệ thống nào cấp phát cho nó. Khi một tuyến đoạn đang tồn tại trong trạng thái này, bạn chỉ có thể khởi động( start) tuyến đoạn. Gọi bất cứ phương thức nào ngoài khởi động ra khi nó đang tồn tại dưới trạng thái này sẽ bị lờ đi và gây ra một IllegalThreadStateException.

Chú ý: Nếu bạn gọi một phương thức của tuyến đoạn mà trạng thái hiện thời của Tuyến đoạn không cho phép, Java sẽ Throw một IllegalThreadStateException. Ví dụ, bạn không thể gọi phương thức stop() cho một tuyến đoạn mà nó đang ở trạng thái new hay không được khởi động.

Khi nào bạn gọi phương thức start() của Thread, thì tuyến đoạn đó đi vào trạng thái ready. Một tuyến đoạn ready là runnable, điều này có nghĩa là nó có thể chạy. Tuy nhiên, một tuyến đoạn runnable có thể không tồn tại ở trong trang thái đang chạy( running) bởi vì CPU có thể không rỗi. Một tuyến đoạn runnable không thể thực sự chạy cho tới khi CPU cấp phát cho nó một khoảng thời gian.

Khi một tuyến đoạn bắt đầu thi hành, nó tồn tại ở trạng thái running. Môt tuyến đoạn chạy cho tới khi nó trở nên không hoạt động( inactive ) hoặc kết thúc( finishes). Một tuyến đoạn đi vào trạng thái not runnable(inactive) khi nào ban gọi phương thức sleep() hoặc suspend() của Thread, hoặc có thể nó trở nên không hoạt động nếu nó phải đợi một tuyến đoạn khác kết thúc và đợi CPU có thời gian rỗi cho nó.

Chú ý: Khi bạn sử dụng phương thức sleep(), bạn phải bắt một InterruptedException, đây là một kiểu biệt lệ được ném khi một chương trình tạm ngừng không chạy trước khi nó kết thúc tự nhiên. Khi bạn sử dụng phương thức sleep(), ban thường làm cho chương trình bị ngắt, vì vậy bạn phải thường xuyên bắt biệt lệ và không hành động gì
ví dụ : try{
if (x = =25) sleep (3000);
if (x = = 75) sleep (5000);
}
catch (InterruptedException e) {}
Khi một tuyến đoạn hoàn thành phương thức run () của nó, khi đó nó đang ở trong trạng thái finished hoặc dead. Một tuyến đoạn cũng có thể đi vào trang thái finished trước khi phương thức run() cuả nó hoàn nếu ban gọi phương thức stop() của tuyến đoạn.
Ban có thể sử dụng phương thức isAlive() để xác định xem một tuyến đoạn còn sống hay không, còn sống có nghĩa là nó đã khởi động nhưng chưa kết thúc. Phương thức isAlive () trả về giá trị false nếu một tuyến đoạn là new hay finished; trường hợp khác thì trả về giá trị true. Bạn không thể phân biệt được tuyến đoạn New và tuyến đoạn Dead(finished). Đồng thời bạn cũng không thể phân biệt được một tuyến đoạn Runnable và một tuyến đoạn Not Runnable( inactive).
Bảng sau đây tóm tắt một vài phương thức hữu ích trong lớp Thread.

Phương thức
sleep() Khai báo
Ngừng tuyến đoạn trong một vài ms
start() Khởi động một tuyến đoạn, gây ra phương thức run() để thi hành
stop() Kết thúc một tuyến đoạn
suspend() hoãn một tuyến đoạn cho tới khi ban sử dụng phương thức resume()
resume() phục hồi lại tuyến đoạn mà bạn đã hoãn.
isAlive() trả về giá trị true hoặc false để xác định xem một tuyến đoạn còn sống hay không
setPriority() Cho phép bạn đăt độ ưu tiên từ 1 tới 10 cho một tuyên đoạn bằng một số nguyên

Ví dụ minh hoạ:
Class ThreadDemo{
public static void main (String [] args){
MyThread mt = new MyThread ();
mt.start();

for (int i =0; i<50; i++)
system.out.println(" i=" + i + ", i*i =" +i *i);
}
}

class MyThread extends Thread{
public void run(){
for (int i =0; i< count; i++){
system.out.print ("*");
system.out.print("\n");
}
}
}

Giải thích:
Khi lớp ThreadDemo chạy, nó tạo ra đối tượng mt của lớp MyThread (lớp này được dãn xuát từ lớp Thread), khởi động một tuyến đoạn của đối tượng đó, và thực thi lệnh trong phương thức run để đưa ra màn hình bảng bình phương các số. Ngược lại, MyThread ghi đè phương thức run() của Thread để dưa ra màn hình một tam giác các ngôi sao.
Khi gõ lệnh java ThreadDemo để chạy ứng dụng, JVM tạo môt tuyến đoạn chính để thi hành phương thức main(). Khi thi hành câu lệnh mt.start();, tuyến đoạn chính báo cho JVM để tạo ra một tuyến đoạn thứ hai nhằm thi hành lệnh trong phương thức run() của đối tượng MyThread. Khi phương thức start() đựơc trả về, tuyến đoạn chính thi hành vòng lặp for của nó để đưa ra bảng bình phương các số, trong khi tuyến đoạn mới thi hành phương thức run() để đưa ra hinh tam giác các ngôi sao

2. Đa tuyến đoạn(multithread).
Người dùng thì biết rằng có thể chạy nhiều chương trình ứng dụng tại một thời điểm. Còn người lập trình thì biết rằng mỗi chương trình có thể chạy nhiều Thread tại một thời điểm.

a. Đa nhiệm(Multitasking)
Khả năng máy tính chạy cùng một lúc nhiều chương trình ,như là trong khi xử lý văn bản có thể nghe nhạc,đó là tính đa nhiệm.
Với tính da nhiệm thì hệ điều hành quyết định khi nào thì chuyển bộ xử lý từ ứng dụng này sang ứng dụng khác đang đợi nó. Hệ điều hành chuyển bộ xử lý mà không cần chương trinh ứng dụng cho phép.
Hệ điều hành bảo vệ mỗi quá trình với tất cả các quá trình khác, lỡ khi một chương trình gặp sự cố, nó sẽ không làm hỏng toàn bộ máy tính.

b. Đa tuyến đoạn (multithreading).
Ngôn ngữ lập trình Java cho phép ban bắt đầu, hay khởi động nhiều tuyến đoạn mà không có vấn đề gì liên quan đến bộ xử lý mà ban đang sử dụng). Nếu bạn sử dụng hệ thống máy tính mà có nhiều hơn một CPU, nhiều tuyến đoạn có thể thi hành cùng lúc.
Nếu bạn sử dụng một máy tính với một bộ xử lý đơn, nhiều tuyến đoạn chia sẻ thời gian của CPU. CPU cấp một lượng thời gian nhỏ cho một nhiệm vụ, và cấp lượng thời gian nhỏ khác cho nhiệm vụ khác. CPU chưa bao giờ thực sự thực hiện hai nhiệm vụ cùng lúc. Thay vào đó, nó thực hiên một chút nhiệm vụ này, sau đó nó lại thực hiện một chút nhiệm vụ khác. CPU thực hiện quá nhanh đến nỗi mà mỗi một nhiệm vụ đang thi hành dường như không bị ngắt quãng giữa chừng.

Định nghĩa: Đa tuyến đoạn là nhiều hơn một tuyến đoạn đang chay trong sự song song hoặc cùng lúc.

Bất cứ một chương trình ứng dụng nào cũng có ít nhất một tuyến đoạn, là Thread đầu tiên của chương trình (hoặc là Thread chính).Chúng ta có thể bắt đầu hay thêm vào cũng như kết thúc những Thread mới khi chúng ta cần,nhưng Thread chính thì giữ tiến trình cùng lúc với chương trình ứng dụng đang chạy
Trong chế độ đa tuyến đoạn:
- Không có cơ chế bảo vệ giữa các tuyến đoạn. Mỗi tuyến đoạn trong Java có thể chạy độc lập với tất cả tuyến đoạn khác trong chương trình đó, song cũng có thể giao tiếp với các tuyến đoạn khác nếu cần, mọi tuyến đoạn đều chia sẻ chung tập hợp các đối tượng và biến.
-Hướng của một tuyến đoạn thông thường khác với hướng của những tuyến đoạn khác. Vi dụ, giả sử có một tuyến đoạn thực hiện chỉ lệnh theo hướng "if " của câu lệnh if-else, trong khi tuyến đoạn khác thi hành chỉ lệnh theo hướng " else".
Vậy làm sao JVM có thể theo dõi được sự thực thi của mỗi tuyến đoạn? JVM sẽ cấp cho mỗi tuyến đoạn phương thức của nó- gọi ngăn xếp( call stack). Ngoài việc theo dõi chỉ lệnh byte hiên thời, phương thức "call stacks" còn theo dõi những biến địa phương, những tham số của phương thức và giá trị trả về của phương thức đó.

3. Tại sao phải sử dụng đa tuyến đoạn:

Người dùng không thích các phần mềm không đáp ứng được yêu cầu. Khi click chuột, người dùng thường mong đợi chương trình đáp ứng ngay lập tức các yêu cầu của họ, thâm chí khi chương trình đó đang trong một hoạt đông cần nhiều thời gian như tổ chức trang lại cho một tài liệu dài hay là đang chờ một thao tác mang hoàn tất. Những chương trình đáp ứng chậm chạp yêu cầu của người sử dụng chúng thường trưng ra một sự thực hiện tồi. Một cách để có thể đáp ứng được nhu cầu đó là sử dụng nhiều tuyến đoạn( multithreading)

Mutithreading giúp ích nhiều cho một chương trình :
- Những chương trình đa tuyến đoạn có giao diện sử dụng đồ hoạ về cơ bản vẫn đáp ứng được yêu cầu của người sử dụng trong khi phải thực hiện các thao tác khác như tổ chức lại trang hay in một tài liệu.
- Những chương trình có sử dụng đa tuyến đoạn đa số đều kết thúc nhanh hơn những chương trinh giống hệt nhưng không sử dụng đa tuyến đoạn. Điều này đặc biệt đúng trong việc chạy nhiều tuyến đoạn trên một máy có nhiều bộ xử lý, ở đó mỗi tuyến đoạn có bộ xử lý riêng .
-Chương trình sử dụng đa tuyến đoạn thường đáp ứng nhanh yêu cầu của người dùng, ngoài ra nó còn có giao diện thân thiện hơn.

Trình duyệt Web HọtJava là một ví dụ của một ứng dụng đa tuyến đoạn. Trong trình duyệt HotJava bạn có thể scroll một trang trong khi nó đang tải một applet hoặc hình ảnh, phát hoạt hình và âm thanh cùng lúc, in một tài liệu ở nền phụ trong khi bạn đang tải một tài liệu mới, hoặc xem ba thuật toán sắp xếp đang trên đường chạy đua đến kết thúc.

4. Hai cách thiết lập tuyến đoạn.
Java thực hiện tuyến đoạn thông qua lơp java.lang.Thread.

4.1 Lớp Thread.
Lớp Thread đuợc định nghĩa trong gói Java.lang, mỗi đối tượng tuyến đoạn mô tả một tuyến đoạn đơn của sự thực thi. Sự thực thi đó thực hiên trong phương thúc run() của Thread

Bảng tóm tắt các hàm dựng của lớp Thread
Thread()
Cấp phát một đối tượng Thread mới.
Thread(Runnable target)
Cấp phát một đối tượng Thread mới.
Tham số:
target - đối tượng mà có phương thức run được gọi

Thread(Runnable target,String name)
Cấp phát một đối tượng Thread mới.
Các tham số
target - đối tượng mà có phương thức run() được gọi
name - Tên của tuyến đoạn mới.
Throw:
SecurityException - Nếu tuyến đoạn hiên thời không tạo được một tuyến đoạn trong nhóm tuyến đoạn được chỉ định

Thread(String name)
Cấp phát một đối tượng Thread mới.
Tham số:
name - tên của tuyến đoạn mới.

Thread(ThreadGroup group,Runnable target)
Cấp phát một đối tượng Thread mới.
Parameters: Các tham số:
group - nhóm tuyến đoạn
target - đối tượng mà có phương thức run() được gọi
Throw:
SecurityException -

Thread(ThreadGroup group,Runnable target,String name)
Cấp phát một đối tượng Thread mới
Các tham số:
group - nhóm tuyến đoạn
target - đối tượng mà có phương thức run() được gọi
name - tên của tuyến đoạn mới.
Throw:
SecurityException -

Thread(ThreadGroup group,Runnable target,String name,long stackSize)
Cấp phát một đối tượng Thread mớiso that it has target as its run object, has the specified name as its name, belongs to the thread group referred to by group, and has the specified stack size.
Các tham số:
group - nhóm tuyến đoạn
target - đối tượng mà có phương thức run() được gọi
name - tên của tuyến đoạn mới.
stackSize -kích thước ngăn xếp được thiết kế cho tuyến đoạn mới, hoặc không có để chỉ định tham số này được bỏ qua.
Throw:
SecurityException -

Thread(ThreadGroup group,String name)
Cấp phát một đối tượng Thread mới
Các tham số:
group - nhóm tuyến đoạn
name - tên của tuyến đoạn mới.
Throw:
SecurityException -

Bảng tóm tắt các phương thức của lớp Thread
static int activeCount()
Trả về số các tuyến đoạn hoạt động trong nhóm tuyến đoạn của tuyến đoạn hiên thời
void checkAccess()
Xác định nếu tuyến đoạn đang chạy hiện thời cho phép sửa đổi tuyến đoạn này
Throws:
SecurityException

static Thread
currentThread()
Trả về một tham chiếu đến đối tượng tuyến đoạn hiện thời đang thi hành
void destroy()
Huỷ một tuyến đoạn.
static int enumerate(Thread[] tarray)
Sao chép vào mảng array mọi tuyến đoạn hoạt động trong nhóm tuyên đoạn của tuyến đoạn hiện thời và những nhóm con của nó.

String
getName()
Trả về tên của tuyến đoạn này
Throws:
SecurityException

int getPriority()
Trả về độ ưu tiên của tuyến đoạn này
ThreadGroup
getThreadGroup()
Trả về nhóm tuyến đoạn của tuyến đoạn này .
static boolean holdsLock(Object obj)

void interrupt()
Ngắt tuyến đoạn này.
Throws:
SecurityException - Nếu tuyến đoạn hiên thời không thể sữa đỗi tuyến đoạn này
static boolean interrupted()
Kiểm tra tuyến đoạn hiên thời có bị ngắt hay không?
boolean isAlive()
Kiểm tra xem tuyến đoạn có còn sống không?.
boolean isDaemon()
Kiểm tra xem tuyến đoan. có bị " chết đói" không?
boolean isInterrupted()
Kiểm tra xem tuyến đoạn này có bị ngắt hay không
void join()
Đợi tuyến đoạn này chết
public final void join()
throws InterruptedException
Throws:
InterruptedException

void join(long millis)
public final void join(long millis)
throws InterruptedException
Throws:
InterruptedException

void join(long millis,int nanos)
p ublic final void join(long millis,int nanos)
throwsInterruptedException
Throws:
IllegalArgumentException
InterruptedException

void resume()
phục hồi lại tuyến đoạn mà bạn đã hoãn..
Throws:
SecurityException

void run()
Nếu hàm dựng tuyến đoạn này sử dụng một đối tượng chạy Runnable riêng biệt, thì phương thức chạy của đối tượng Runnable được gọi; nếu không, phương thức này không làm gì . Lớp con của Thread nên ghi đè phương thức này.
void setName(String name)
Thay đổi tên của tuyến đoạn này bằng tham số name.
void setPriority(int newPriority)
Thay dổi độ ưu tiên của tuyến đoạn này.
Throws:
IllegalArgumentException
SecurityException

static void sleep(long millis)
Làm cho tuyến đoạn đang thi hành hiên thời ngủ trong vài ms được chỉ định
Tham số:
millis - Khoảng thời gian ms để ngủ.
Throw:
InterruptedException Nếu tuyến đoạn khác ngắt tuyến đoạn hiện thời.

static void sleep(long millis,int nanos)
Làm cho tuyến đoạn đang thi hành hiên thời ngủ trong vài ms và vài nano giây được chỉ định
Throws:
IllegalArgumentException
InterruptedException

void start()
Làm cho tuyến đoạn này bắt đầu thi hành, JVM gọi phương thức run của tuyến đoạn
Throws:
IllegalThreadStateException

void stop()
Ngừng một tuyến đoạn
Throws:
SecurityException .


void suspend()
hoãn một tuyến đoạn cho tới khi ban sử dụng phương thức resume()
Throws:
SecurityException

String
toString()
Trả về một chuỗi giới thiệu về tuyến đoạn này, bao gồm tên tuyến đoạn, thứ tự ưu tiên, và nhóm tuyến đoạn


static void yield()
Làm cho đối tượng tuyến đoạn hiện thời đang thi hành ngừng tạm thời và cho phép các tuyến đoạn khác thi hành.


4.2 Tuỳ chỉnh phương thức run() của lớp Thread.

Lớp Thread chứa phương thức run() để thông tin cho hệ thống cách thức thi hành tuyến đoạn như thế nào. Nội dung phương thức run() của tuyến đoạn mặc định của lớp Thread là rỗng. Thực tế thì điều nay không có ích lợi gì, vì vậy lớp Thread định nghĩa API (API cho phép một đối tượng Runnable cung cấp một phương thức run thú vị hơn cho một tuyến đoạn).
Chúng ta sử dụng phương thức start() với một đối tương Thread cụ thể để thông tin cho hệ thống bắt đầu thi hành một tuyến đoạn.
Khởi động nhiều hơn một đối tượng tuyến đoạn, chúng ta sẽ có được chương trình đa tuyến đoạn

Có hai cách để tạo một tuyến đoạn thi hành mới:

a.Thiết lập tuyến đoạn bằng cách thừa kế từ lớp Thread.

- Viết lớp mở rộng từ lớp Thread: lớp con này sẽ ghi đè phương thức run của lớp Thread
Ví dụ: một tuyến đoạn mà tìm các số nguyên tố lớn hơn một giá trị đã được khởi đâù được viết như sau:
class PrimeThread extends Thread {
long minPrime;
PrimeThread(long minPrime) {
this.minPrime = minPrime;
}

public void run() {
// tìm các số nguyên tố lớn hơn một giá trị đã được khởi đâù
. . .
}
}

-Trong phương thức main():
+ Định nghĩa đối tượng lớp con
+ Khởi động tuyến đoạn

Ví dụ : Đoạn mã sau sẽ tạo một tuyến đoạn và khởi động nó chạy:

PrimeThread p = new PrimeThread(143);
p.start();

Ví dụ minh hoạ chương trình tạo tuyến đoạn bằng cách tạo lớp con và ghi đè phương thức run() của Thread

Class ThreadDemo{

public static void main (String [] args){

// bắt đầu tuyến đoạn chính
MyThread mt = new MyThread ();
mt.start();
// Thực hiện công việc của tuyến đoạn chính đông thời thực hiện phương thức run của tuyên // đoạn thứ hai mới tạo ra
for (int i =0; i<50; i++)
system.out.println(" i=" + i + ", i*i =" +i *i);
}
}

class MyThread extends Thread{
public void run(){
for (int i =0; i< count; i++){
system.out.print ("*");
system.out.print("\n");
}
}
}


b.Thiết lập tuyến đoạn bằng cách thi công giao diên Runnable.
-Khai báo một lớp thực thi giao diện Runnable: lớp này sau đó sẽ thực thi phương thức run()
Ví dụ: một tuyến đoạn mà tìm các số nguyên tố lớn hơn một giá trị đã được khởi đâù được viết như sau:
class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}

public void run() {
// compute primes larger than minPrime
. . .
}
}

-Trong phương thức main()
+ Định nghĩa đối tượng của lớp, dùng nó tạo đối tượng tuyến đoạn
+ Kích hoạt tuyến đoạn.

Ví dụ : Đoạn mã sau sẽ tạo một tuyến đoạn và khởi động nó chạy

PrimeRun p = new PrimeRun(143);
new Thread(p).start();

Ví dụ minh hoạ chương trình tạo tuyến đoạn bằng cách thi công giao diện Runnable

Thay vì tạo lớp con của Thread, lớp Clock thực hiện giao diên Runnable (chính vì vậy nên nó thực hiện phương thức run được định nghĩa trong nó). Clock sau đó sẽ tạo một tuyến đoạn và cung cấp chính nó như là một tham số của hàm dựng Thread. Khi được tạo theo cách naỳ, lớp Thread nhận phương thức rụn của nó từ đối tượng được chuyển vào trong hàm dựng.

import java.awt.Graphics;
import java.util.*;
import java.text.DateFormat;
import java.applet.Applet;

public class Clock extends Applet implements Runnable {
private Thread clockThread = null;
public void start() {
if (clockThread == null) {

clockThread = new Thread(this, "Clock");
// clockThread tồn tại trong trạng thái New Thread, bạn chỉ có thể start tuyến đoạn
// chú ý rằng: this là tham số đầu tiên của hàm dựng Thread . Tham số đầu tiên phải //thi hành giao diên Runnable và cung cấp tuyến đoạn với phương thức run của nó. // //Tham số thứ hai chỉ là tên cho tuyến đoạn

clockThread.start();
//Phương thức start tạo ra những tài nguyên hệ thống cần thiết để chạy //tuyến đoạn, lập biểu tuyến đoạn để chạy, và gọi phương thức run của tuyến //đoạn. Phương thức run của clockThread là một định nghĩa của lớp Clock
//Sau khi phương thức start trả về, tuyến đoạn là " running".
}
}


public void run() {
Thread myThread = Thread.currentThread();
while (clockThread == myThread) {
repaint();
try {
Thread.sleep(1000);
} catch (InterruptedException e){ }
}
}
public void paint(Graphics g) {
// lấy thời gian và biễu diễn nó qua ngày
Calendar cal = Calendar.getInstance();
Date date = cal.getTime();
// định dạng nó và hiển thị nó
DateFormat dateFormatter = DateFormat.getTimeInstance();
g.drawString(dateFormatter.format(date), 5, 10);
}

// Ghi đè phương thưc stop() của applet, không phải của lớp Thread
public void stop() {
clockThread = null;
}
}

Phương thức run của applet Clock lặp cho tới khi trình duyệt bảo nó nghừng. Trong mỗi lần lặp, clock sẽ sửa lại việc hiển thị của nó. Phương thức paint đưa ra thời gian là bao nhiêu, định dạng nó và hiển thị nó
vòng lặp sẽ thoát nếu tuyến đoạn đang thi hành hiên thời không phải là clockThread. Khi nào xảy ra trường hợp này?
Khi bạn rời trang này, thì ứng dụng mà applet đang chạy trong đó sẽ gọi phương thức stop của applet. Phương thức này sau đó sẽ đặt clockThread là giá trị null, bởi vậy báo cho vòng lặp main trong phưong thức run để kết thúc
Nếu bạn vào lại trang này, phương thức start được gọi trở lại và clock khởi động lại vói tuyến đoạn mới.

c. Sử dụng phương pháp thiết lập nào?:

Khi ban đối mặt với một tình huống mà ở đó một lớp có thể hoặc là dẫn xuất từ Thread hoặc thực hiện Runnable, thì bạn phải chon hướng nào?
Vì Java ứng dụng tính thừa kế đơn nên nếu lớp đó dẫn xuất từ một lớp khác thì bạn phải thực thi Runnable. Tuy vậy, nếu lớp đó không dẫn xuất từ một lớp khác, hãy suy nghĩ tới tên của lớp. Tên đó sẽ gợi ra đối tuợng của lớp đó là hoạt động hay không?. Nếu hoạt động thì lớp đó nên dẫn xuất từ Thread. Ngược lại, lớp đó nên thực hiên Runnable.

4.Thứ tự ưu tiên trong sự thực thi các tuyến đoạn

Hầu hết các máy tính chỉ có một CPU, vì thế các tuyến đoạn phải chia sẻ CPU với các tuyến đoạn khác. Sự thực thi của nhiều tuyến đoạn trên một CPU đơn, theo một thứ tự nào đó, được gọi là sự lập danh mục (sheduling).
Trong Java, mỗi tuyến đoạn đều có một thứ tự ưu tiên trong danh sách truy cập ưu tiên đến các tài nguyên của hệ điều hành. Thứ tự ưu tiên của mỗi đối tượng tuyến đoạn được định lượng bởi một giá trị nguyên từ 1-10, 5 là giá trị mặc định nếu bạn không đăng kí độ ưu tiên cho đối tượng tuyến đoạn.
Một tuyến đoán đều có thể nhường quyền ưu tiên của chúng bằng phương thức yield() bất cứ khi nào. Các tuyến đoạn chỉ có thể nhường CPU cho các tuyến đoạn khác có độ ưu tiên giống nó- cố gắng nhường cho một tuyến đoạn có độ ưu tiên tháp hơn sẽ bị lờ đi.
Khi tất cả các tuyến đoạn có thể chạy trong hệ thống có cùng độ ưu tiên, bộ lập biểu sẽ chọn tuyến đoạn kế tiếp để chạy trong một thứ tự danh mục luân phiên, không ưu tiên và bình đẳng.
Chúng ta có thể thay đổi thứ tự ưu tiên của một tuyến đoạn bằng cách sử dụng phưong thức setPriority(). hoặc xác định thứ tự ưu tiên của một tuyến đoạn bởi phương thức getPriority().
Lớp Thread chứa 3 hằng:
+ Độ ưu tiên thấp nhất (1) được đặt tên là MIN_PRIORITY
+ Độ ưu tiên cao nhất (10) được đặt tên là MAX_PRIORITY.
+ Độ ưu tiên trung bình (5) được đặt tên là NORM_PRIORITY
ví dụ : Đặt thứ tự ưu tiên cho showA và show B( là hai đối tượng của môt lớp ShowThread được dẫn xuất từ lớp Thread )
showB.setPriority(Thread.MIN_PRIORITY)
showA.setPriority(Thread.MAX_PRIORITY)

Khi chạy chương trình Java, tuyến đoạn được phép chạy có độ ưu tiên cao nhất sẽ chạy đầu tiên..Nếu nhiều tuyến đoạn có độ ưu tiên giống nhau, chúng sẽ chạy trong sự luân phiên. Tuyến đoạn có độ ưu tiên thấp hơn chỉ có thể chạy khi tuyến đoạn có độ ưu tiên cao hơn là không hoạt động( ví dụ như là khi chúng đã kết thúc, đã tạm hoãn hoặc đang ngủ)
Nói chung, khi một tuyến đoạn ThreadA có độ ưu tiên cao hơn tuyến đoạn ThreadB, ThreadA sẽ là đang chạy và tuyến đoạn ThreadB sẽ phải đợi. Tuy vây, thỉnh thoảng Java sẽ chọn để chạy ThreadB để tránh tình trang " chết đói". Tình trạng này xảy ra khi một tuyến đoạn không thể thực hiên bất cứ hoạt động nào bởi độ ưu tiên của các tuyến đoạn khác

B. Biãût lãû(Exception)
I/Giới thiệu sơ lượt về biệt lệ trong Java
 Việc xử lý và đối phó với các lỗi và biệt lệ trong quá trình thực thi chương trình gặp rất nhiều khó khăn trong nhiều ngôn ngữ lập trình. Để khắc phục được điều đó người ta đã đưa ra nhiều phương pháp như:sử dụng phương thức lập trình tiên tiến ,hướng đối tượng để giảm bớt lỗi,mã hoá v.v..Trong ngôn ngữ Java thì việc xử lý lỗi và biệt lệ được xử lý dưới dạng một đối tượng.Chính nhờ việc chuyển lỗi và các biệt lệ thành những đối tượng đã giúp cho việc kiểm soát lỗi trở nên đơn giản và dễ kiểm soát chương trình hơn.
II/Tìm hiểu các khái niệm và các phương thức dùng trong việc xử lý biệt lệ
II.a.Thế nào là biệt lệ ?
 Chúng ta có thể hiểu biệt lệ là một sự kiện xảy ra trong quá trình thực thi chương trình và nó ngăn cản những dòng lệnh tiếp theo của chương trình khiến chương trình không hoàn tất được .Trong Java biệt lệ có thể được định nghĩa như sau:
 Biệt lệ là cách gọi đối tượng thuộc lớp biệt lệ (Exception class )chuyên làm nhiệm vụ báo hiệu tình huống bất thường vào lúc chương trình thực thi.Ví dụ như :những lỗi chia cho 0, chỉ số truy cập ngoài mãng hoặc ép sai kiểu ….là những lỗi có thể phát sinh biệt lệ.
Để thấy rõ hơn biệt lệ là như thế nào và nó gây ra gì cho chương trình ta hãy xét ví dụ sau:
Ví dụ 1
class ExampleException {
public static void main(String[] args) {
int d=0;
int a= 12/0;
System.out.println(“day la de tai do TRINH + HANG thuc hien”);
}
}
 Ở ví dụ này ta thấy hệ thống phát hiện ra việc chia cho 0 nên đã ngăn việc thực thi chương trình lại. Nên kết quả của chương trình như sau:

---------- java ----------
java.lang.ArithmeticException: / by zero
at ExampleException.main(ExampleException.java:5)
Exception in thread "main" Normal Termination
Output completed (0 sec consumed).

II.b.Nguyên nhân gây ra biệt lệ
Có thể phát sinh từ hệ thống thực thi của Java như: Vi phạm các quy tắc của ngôn ngữ hoặc những ràng buộc của môi trường thực thi của Java
Hoặc từ việc biên dịch chương trình thường báo những trạng thái lỗi cho người sử dụng
Trong java trình xử lý biệt lệ đã được cài sẵn hữu ích trong việc gỡ rối chương trình.Tuy nhiên , bạn muốn tự mình xử lý các biệt lệ đó thì Java đã đưa ra một mô hình xử lý biệt lệ ngăn ngừa và xử lý lỗi thực thi chương trình
II.c.Mô hình xử lý biệt lệ
try{ //khối cần được giám sát lỗi
}
catch(Exception type1 exOb){
//xử lý cho biệt lệ Exception type1
}
catch(Exception type2 exOb){
//xử lý cho biệt lệ Exception type1 }
//…
finally{
//khối lệnh cần thực hiện trước khi khối thử kết thúc
}
II.d. Giải thích công dụng của các từ khoá trong biệt lệ
 try/catch
Chúng ta muốn giám sát những biệt lệ có thể phát sinh từ những câu lệnh thì đặt những câu lệnh của biệt lệ vào trong khối thử(try block) và việc xử lý biệt lệ được diễn ra trong khối bắt (catch block) đặt ngay sau khối thử.
Khối biệt lệ còn được gọi là trình xử lý biệt lệ (Exception handler).Thông qua khối bắt ta có thể khắc phục các lỗi phát sinh trong quá trình dịch chương trình, bảo đảm cho chương trình tiếp diễn bình thường.
 Throw
Hầu hết các biệt lệ được kích hoạt tự động từ hệ thống Java. Tuy nhiên chương trình của bạn cũng có thể kích hoạt một biệt lệ trực tiếp bằng cách sử dụng lệnh throw.
Dạng tổng quát như sau:
try{
if(b<0)
{ throw new myException }
}
. Do vậy có hai cách để có một đối tượng
• dùng tham số trong mệnh đề catch
• hoặc tạo ra một đối tượng mới bằng toán tử new.
 throws
Nếu một phương thức có thể sinh biệt lệ mà nó không quản lý thì nó phải chỉ ra điều này để nơi gọi có thể tránh biệt lệ đó. Để thực hiện điều này ta thêm throws vào phần khai báo của phương thức, sau từ khoá throws thì ta liệt kê tất cả các kiểu biệt lệ mà phương thức có thể gây ra.
Mô hình như sau:
class Example{
public void exceptionExample() throws ExException, LookupException {
try{
//các câu lệnh }
catch(ExException t) {….}
catch(LookupException ) {….}
}
}
 finally
• Khi biệt lệ xảy ra,trình tự thi hành trong phương thức thay đổi.Tuỳ thuộc vào các trường hợp, có khả năng một biệt lệ làm cho phương thứ kết thúc sớm(có nghĩa là một số lệnh sẽ không được thực hiện khi có biệt lệ xảy ra ). Để giải quyết vấn đề này thì ta sử dụng từ khoá finally
• finally tạo ra một khối mà các câu lệnh trong đó sẽ được thi hành sau khi một khối try/catch nhưng trước khối try/catch kế tiếp.
• Khối finally được thi hành bất chấp biệt lệ có xảy ra hay không. nếu một biệt lệ xảy ra khối finally sẽ thi hành ngay khi cả khi biệt lệ đó không khớp với biệt lệ được khai báo trong catch



no Exception Exception xảy ra







III/Các kiểu của biệt lệ
III.a. Biệt lệ có sẵn

Được biểu diễn bởi các cây ở hình sau:














 Trong gói java.lang thì tất cả các lớp biệt lệ đều là lớp con của lớp Throwable. Ngay dưới của throwable là hai lớp con mà nó chia biệt lệ thành hai nhánh khác biệt: Exception và error
A.lớp Exception
 Lớp Exception thường mô tả những lỗi thông thường là do sai lầm từ phía người sử dụng và biệt lệ này thì không ngăn cản chương trình.
 Các biệt lệ Exception có thể được ném bởi người lập trình bằng việc sử dung câu lệnh throw hoặc bởi bản thân chương trình dịch Java
Lớp Exception có lớp con quan trọng nhất là RuntimeException
o Do java .lang được nhìn thấy không rõ ràng trong tất cả các chương trình java nên hầu hết các biệt lệ xuất phát từ Runtime Exception tích hợp tự động vào chương trình.
o Trong đó có những biệt lệ không cần đưa throws vào phương thức nào cả, và những biệt lệ này được gọi là biệt lệ không kiểm tra (có nghĩa là trình biên dịch không cần kiểm tra xem phương thức có xử lý hay kích hoạt chúng hay không)(bảng 1)
o Bên cạnh đó có những biệt lệ cần được liệt kê trong throws của phương thức nếu như phương thức đó có khả năng gây ra một trong những biệt lệ và không xử lý. Những biệt lệ này được gọi là biệt lệ có kiểm tra(bảng 2)

Những biệt lệ không kiểm tra là:

Biệt lệ Ý nghĩa
ArithmeticException lỗi số học như chia cho 0
ArrayIndexOutOfBoundsException chỉ số mảng nằm ngoài khoảng
ArrayStoreException Gán sai kiểu cho một phần tử của mảng
ClassCastException Ép sai kiểu
IllegalArgument Exception gọi phương thức có tham số không hợp lệ
IllegalMonitorStateException Thao tác theo dõi không hợp lê
IllegalStateException Môi trường hoặc ứng dụng trong trạng thái không hợp lệ
IndexOutOfBoundsException chỉ số nằm ngoài khoảng
NegativeArraySizeException tạo mảng có kích thức âm
NullPointerException sử dụng sai con trỏ null
NumberFormatException lỗi khi chuyển sang số
SecurityException lỗi vi phạm bảo mật
StringIndexOutOfBounds cố truy xuất vị trí ngoài khoảng chuỗi
Bảng 1

Những biệt lệ có kiểm tra

ClassNoFound Exception Không tìm thấy lớp
CloneNotSupported Exception Cố sao chép một đối tương nhưng không thể hiện giao diện Cloneable
Illegal Access Exception Truy xuất đến lớp bị từ chối
Instantiantion Exception Cố tạo đối tượng của lớp giao diện hay lớp trừu tượng
Interrupted Exception Một tiểu trình vừa bị gián đoạn bởi một tiểu trình khác
NoSuchfield Exception Truy xuất tới trường không tồn tại
NoSuch Method Exception Truy xuất tới phương thức không tồn tại

Bảng 2
B.lớp Error
 Lớp Error thường diễn tả những lỗi do sự bất ổn nào đó trong hệ thống Java lúc chạy làm cho chương trình chạy được nữa.
 Các biệt lệ Error chỉ được ném đi bởi trình thông dịch Java và bạn không thể bắt biệt lệ này được

Lỗi Nguyên nhân
AbstractMethodError Thử gọi một phương thức trừu tượng
ClassCircularityError lỗi này thì không được dử dụng
ClassFormatError định dạng lớp nhị phân không hợp lệ
IllegalAccessError thử truy cập đến một đối tượng không tới được
IncompatibleClassChangeError một lớp được sử dụng không đúng
InstantiationError thử trình bày một lớp trừu tượng
InternalError lỗi trong cách ghi lời giải thích
NoClassDefFoundError Không tìm thấy lớp định nghĩa
NoSuchFieldError Không tìm thấy trường đã yêu cầu
NoSuchMethodError Không tìm thấy phương thức yêu cầu
OutOfMemoryError nằm ngoài bộ nhớ
StackOverflowError Tràn ngăn xếp
ThreadDeath chỉ ra giới hạn của tuyến đoạn
UnknownError Không biết lỗi trên máy ảo
VerifyError Không thể kiểm tra được mã bytecode


C.Các biệt lệ tồn tại ở các gói khác như:

Các biệt lệ trong gói java.io
EOFException
Dữ liệu đầu vào file hoặc vào luồng đã bị kết thúc bất thình lình
InterruptedIOException
Thao tác vào ra đã bị ngắt
IOException
Việc nhập xuất dữ liệu của một loại nào đó đã được xảy ra(xuất hiện)
UnsupportedEncodingException
Ký tự mã đó không được xác nhận


Biệt lệ trong gói javax.microedition.rms
InvalidRecordIDException
Biệt lệ này được ném để chỉ một thao tác không thể được hoàn thành bởi vì địa chỉ bản ghi đã không có giá trị
RecordStoreException
Một biệt lệ không rõ đã xảy ra trong thao tác ghi đĩa
RecordStoreFullException
Biệt lệ này xảy ra khi một thao tác không được hoàn thành bởi vì bản ghi được lưu trữ trong hệ thống đã đầy
RecordStoreNotFoundException
Biệt lệ này xảy ra khi một thao tác không được hoàn thành bởi vì bản ghi được lưu trữ trong hệ thống đã không được tìm thấy
RecordStoreNotOpenException
Cố gắng mở bản ghi đã bị đóng nhưng không được



III.b/Biệt lệ tự tạo:
Mặc dù những biệt lệ cung cấp sẵn trong Java xử lý hầu hết các lỗi thông thường, thế nhưng ta vẫn muốn tạo ra những kiểu biệt lệ của riêng chúng ta, để xử lý những đặc thù cho những ứng dụng do chính chúng ta tạo nên, thì trong Java cũng cho phép chúng ta tạo nên những lớp biệt lệ như thế.
III.b.1/ Cách tạo các lớp biệt lệ :
 Trước hết ta đinh nghĩa lớp biệt lệ tự tạo là lớp con của lớp Exception (ở đây dĩ nhiên lớp biệt lệ tự tạo này cũng là lớp con của lớp Throwable)
 Ví dụ ta tạo ra lớp biệt lệ có tên là MyException và không thực hiện gi hơn ngoài những gì lớp Exception thực hiện.
 Khi đólớp MyException có hai phương thức :phương thức tạo dựng mặc định(phương thức không chứa tham số), và phương thức nhận chuỗi làm tham số.phương thức tạo dựng thứ hai chỉ gọi phương thức tạo dựng của lớp cha (thông qua super()) bằng chuỗi:

public class My Exception extends Exception {
//hàm tạo dựng mặc định
public My Exception (){………}
//hàm tạo dựng với lời nhắn của biệt lệ
public My Exception (string message){
super (message)
}
}
Khi muốn ném biệt lệ do chinh bạn tạo ra thì ta cũng ném và xử lý như mọi biệt lệ thông thường khác
III.b.2.Ví dụ:
class MyArraySiseException extends NegativeArraySizeException{
MyArraySiseException(){
super(“CANH BAO :loi ban mac phai la kich co cua mang khong hop le”);
}
};

class myException{
int size, array[];
myException(int s) {
size= s;
try { checkSize();
}
catch (MyArraySiseException e) {
System.out.println(e);
}
}
void checkSize() throws MyArraySiseException {
if(size<0)
throw new MyArraySiseException();
else System.out.println(“kich co cua mang la dung”);
array= new int[3];
for (int i=0 ;i<3 ;i++ )
array=i+1;
}
public static void main(String arg[]) {
System.out.println(“day la chuong trinh thu biet le tu tao”);
new myException(9);
System.out.println();
new myException(-9);
}
}

II.2.2.b/Kết quả chương trình:

---------- java ----------
kich co cua mang la dung

MyArraySiseException: CANH BAO :loi ban mac phai la kich co cua mang khong hop le
Normal Termination
Output completed (0 sec consumed).
IV/ Cơ chế xử lý biệt lệ
IV.a. Các cở sở xử lý biệt lệ
 Một biệt lệ trong Java là một đối tượng miêu tả trạng thái biệt lệ (lỗi) xảy ra trong một đoạn mã. Khi một biệt lệ được sinh ra thì đối tượng đại diện cho biệt lệ đó được tạo ra và được chuyển cho phương thức gây nên lỗi. Phương thức đó có thể lựa chon một trong hai khả năng sau: tự xử lý biệt lệ hoặc bỏ qua. Có thể cho rằng một trong hai cách thì biệt lệ vẫn bị chặn và xử lý
IV.b. Ném và bắt biệt lệ thông thường
IV.b.1. Biệt lệ không được xử lý:
 Sau đây ta xét một ví dụ 1để xem biệt lệ hoạt động như thế nào?

class ExampleException {
public static void main(String[] args) {
int d=0;
int a= 12/0;
System.out.println(“day la de tai do TRINH + HANG thuc hien”);
} }

 Kết quả:
---------- java ----------
java.lang.ArithmeticException: / by zero
at ExampleException.main(ExampleException.java:5)
Exception in thread "main" Normal Termination
Output completed (0 sec consumed).


 Phân tích ví dụ 1:
• Khi hệ thống thực thi Java phát hiện ra lỗi chia 0, nó tạo ra một đối tượng biệt lệ và chuyển biệt lệ này đi.Điều này làm cho việc thực thi chương trình ExampleException bị dừng lại. Đó là do khi một biệt lệ được chuyển đi thì nó phải bắt lấy bởi một trình xử lý biệt lệ ngay lập tức.Trong ví dụ này, chúng ta không cung cấp bất cứ một trình xử lý biệt lệ nào cho nên biệt lệ xảy ra đã được trình xử lý biệt lệ mặc định chặn lại.
• Trình xử lý mặc định này có sẵn trong Java. Bất cứ biệt lệ nào không bị chặn lại sẽ được xử lý mặc định trong trình xử lý mặc định.
• Trình xử lý mặc định hiển thị một chuỗi mô tả biệt lệ, in nội dung của stack tại thời điểm xảy ra biệt lệ và sau đó kết thúc chương trình. Do vậy câu hiển thị System.out.println(“chao TRINH + HANG”); đã không được thực hiện.
 Ở ví dụ trên ta thấy được một biệt lệ hoạt động như thế nào khi chưa được xử lý.
IV.b.2.Một biệt lệ được xử lý thì sẽ hoạt động như thế nào?
Xét ví dụ sau:
class vidu2{
public static void main(String[] args) {
int d,a;
try{
d=0;
a=42/d;
System.out.println(“chao TRINH + HANG”);
}
catch (ArithmeticException t){
System.out.println(“LOI CHIA CHO ZORE”);
}
System.out.println(“VIEC BAT BIET LE DA THANH CONG NEN CHUONG TRINH DUOC TIEP TUC”);
}
}
Kết quả
---------- java ----------
LOI CHIA CHO ZORE
VIEC BAT BIET LE DA THANH CONG NEN CHUONG TRINH DUOC TIEP TUC
Normal Termination
Output completed (1 sec consumed).
Phân tích
chương trình mắc phải biệt lệ chia cho 0 nhưng được xử lý bằng khối lệnh catch(ArithmeticException t), do vậy biệt lệ đã được xử lý nên chương trình vẫn tiếp tục được thực hiện
 Qua đó ta thấy biệt lệ sau khi được xử lý thì chương trình vẫn được tiếp tục. và việc bắt biệt lệ đó đã diễn ra như sau: sau khi ta giám sát đoạn mã cần bắt biệt lệ trong khối try , thì khi chương trình xảy ra biệt lệ thì chương trình dịch sẽ chuyển quyền xử lý cho khối catch. Sau đó thực hiện việc xử lý biệt lệ trong catch(báo lỗi…), thực hiện xong thì trình biên dich vẫn tiếp tục chương t rình mà không quay lại khối try để thực hiên các lệnh còn lại.
IV.c. Thứ tự các khối biệt lệ
• Ở một số trường hợp nếu như trong một khối try có nhiều biệt lệ được sinh ra để xử lý nó ta cần hai hay nhiều hơn hai mệnh đề catch và mỗi cái trong chúng sẽ bắt các biệt lệ khác nhau.
• Khi biệt lệ phát sinh thì mỗi mệnh đề catch sẽ xem xét theo thứ tự và mệnh đề đầu tiên đúng kiểu với biệt lệ đã xảy ra sẽ thi hành, những mệnh đề khác bị bỏ qua và chương trình tiếp tục với các dòng lệnh sau khối try/catch đó
• Chú ý khi dùng nhiều catch thì biệt lệ con phải được đặt trước biệt lệ cha bởi vì: một mềnh đề catch sử dụng để bắt một biệt lệ sẽ bắt những biệt lệ của lớp đó và tất cả các biệt lệ con của nó. Chính vì thế lớp con sẽ không bao giờ được xử lý nếu như nó để sau lớp cha
Xét ví dụ sau:
class VIDU3NHIEUCATCH {
public static void main(String[] args) {
try{
int a = 1; System.out.println(“a=”+a);
int b=42/a;
int c[]={1};
c[42]=-99;
}
catch(ArithmeticException t){
System.out.println(“CHIA CHO ZERO: “+t);
}
catch (ArrayIndexOutOfBoundsException h){
System.out.println(“CHI SO NAM NGOAI MANG”+h);
}
System.out.println(“SAU KHI THUC HIEN XONG KHOI TRY VA CATCH TREN”);
}
}
Kết quả :
---------- java ----------
a= 1
CHI SO NAM NGOAI MANG java.lang.ArrayIndexOutOfBoundsException
SAU KHI THUC HIEN XONG KHOI TRY VA CATCH TREN
Normal Termination
Output completed (0 sec consumed).
Phân tích:
Khi đó khối try kiểm tra câu lệnh trước nếu có phát sinh biệt lệ (a=0) thì khối bắt đầu tiên sẽ hoạt động . Sau khi xử lý xong thì thực hiện câu lệnh System.out.println(“SAU KHI THUC HIEN XONG KHOI TRY VA CATCH TREN”); và không quay trở lại khối try để thực hiện các câu lệnh tiếp theo do vậy biệt lệ ArrayIndexOutOfBoundsException tiếp theo sẽ không được sử lý. Còn nếu biệt lệ đầu tiên không xảy ra (a≠0) thì biệt lệ thứ 2 mới được bắt và xử lý
IV.d. Lây lan biệt lệ
Khi dùng phương thức ném biệt lệ, bạn buộc phải bắt biệt lệ đó hoặc ném nó ra khỏi phương thức đang viết.
Ví dụ :
Giả sử ta đang viết phương thức A(), và muốn sử dụng phương thức B() trong phương thức A().Giả sử phương thức B() ném biệt lệ có tên THException thì ta có thể xử lý biệt lệ THException đó trong khối catch hoặc có thể ném biệt lệ này trong phần nhận diện của phương thức A().
Biệt lệ sẽ được xử lý như sau:



bắt đầu



Bước 1:gọi A()




Bước2: gọi B()




Bước3: B()ném biệt lệ



Bước4: A()ném biệt lệ



Bước5: main() ném biệt lệ

 Phương thức main() gọi phương thức A(), đến lượt phương thức A() gọi phương thức B().Sau đó phương thức B()ném biệt lệ TH Exception .
• Trường hợp phương thức A() không bắt được biệt lệ thì máy tính sẽ chuyển biệt lệ lên cho phương thức main().Nếu phương thức main() không bắt được thì trình dịch sẽ thông báo lỗi hợp
Nếu phương thức A() ném biệt lệ THException sau đó một phương thức bất kỳ sử dụng phương thức A() thì đều phải xử lý hoặc ném biệt lệ đó tương tự như vậy
IV.e. Biệt lệ lồng
• Các câu lệnh try có thể được tổ hợp để tạo nên nhiều cấp độ cho khả năng xử lý biệt lệ. Điều này thực hiện bằng cách lồng một phương thức hoặc một khối câu lệnh chứa trong một câu lệnh try vào một câu lệnh try khác.
• Mỗi khi thi hành đến một lệnh try, ngữ cảnh của biệt lệ đẩy vào ngăn xếp. Khi một biệt lệ được ném ra mà khối câu lẹnh try lhoong bắt được thì biệt lệ tiếp tục được ném cho khối câu try lồng bên ngoài và cứ thế. Câu lệnh try lồng bên ngoài có thể bắt lấy biệt lệ và xử lý bằng những mệnh đề catch của nó.
• Số câu lệnh try là không giới hạn.
• Khi biệt lệ đã được mệnh đề catch của câu lệnh try bắt lấy, biệt lệ đó có thể được ném tiếp. khi một biệt lệ được ném tiếp, nó có thể được mệnh đè catch của câu lệnh try lồng bên ngoài bắt lấy và xử lý.
• Mệnh đề catch cao hơn có thể thực hiện bất kỳ việc xử lý thứ cấp nào.
• Ví dụ:
import java.io.*;
class nesttry{
public static void main(String[] args){
try{
//int a=1;
int a=2;
System.out.println("a= "+a );
try{
if (a= =1) a=a/(a-a);
if (a= =2){
int c[]={1};
c[42]=99;
}
}
catch (ArrayIndexOutOfBoundsException e){
System.out.println("nam ngoai vung truy cap cua mang "+e); }
}
catch (ArithmeticException t){
System.out.println("chia 0!");
}
}
}

kết quả:
---------- java ----------
a= 1
chia 0!
Normal Termination
Output completed (0 sec consumed).
---------- java ----------
a= 2
nam ngoai vung truy cap cua mang java.lang.ArrayIndexOutOfBoundsException
Normal Termination
Output completed (0 sec consumed).

Tóm lại một biệt lệ sẽ được xử lý như sau:
• Câu lệnh try thực hiện một khối câu lệnh.Nếu một biệt lệ được ném ra trong khi thực hiện khối câu lệnh thì sẽ kết thúc việc thực hiện khối câu lệnh đó. Đồng thời kiểm tra các mệnh đề trong catch xem thử mệnh đề nào bắt được biệt lệ đã ném ra. Nếu không có mệnh đề catch nào có thể bắt biệt lệ thì biệt lệ sẽ được chuyển lên cho lệnh try cấp trên.Việc xử lý biệt lệ cứ tiếp tục cho đến khi biệt lệ được bắt lấy hoặc không có câu lệnh try nào cả.
• Mệnh đề catch có thể bắt lấy biệt lệ nếu gán đối số một cách hợp lệ cho đối tượng được ném đi trong câu lệnh throws. Nếu đối số của mệnh đề catch là một lớp thì mệnh đề catch có thể bắt được đối tượng của lớp đó và những đối tượng thuộc lớp con của lớp đó. Còn nếu đối số của mệnh đề catch là một giao diện thì mệnh đề catch có thể bắt được những đối tượng thi công giao diện đó.
• Câu lệnh try thử các mệnh đề catch theo thứ tự và chọn mệnh đề đầu tiên có thể bắt được biệt lệ đã ném ra. Sau đó câu lệnh try thực hiện các câu lệnh bên trong mệnh đề catch. nếu có mệnh đề finally trong khối lệnh try thì những câu lệnh trong mệnh đề finally sẽ được thực hiện sau khi thực hiện xong biệt lệ của mệnh đề catch. Sau đó chương trình sẽ tiếp tục thực hiện sau câu lệnh try.
V/ Thuận lợi của việc sử dụng biệt lệ :
Sử dụng biệt lệ để quản lý lỗi trong Java đã vượt qua các công nghệ quản lý lỗi truyền thống:
1/ Việc chuyển các lỗi thành các đối tượng thuộc các kiểu biệt lệ khác nhau đã giúp cho chương trình trở nên minh bạch, rõ ràng , giúp cho người lập trình dễ gỡ rối chương trình trong khi lập trình
2/Việc chuyển các biệt lệ cần bắt vào ngăn xếp theo thứ tự đã giúp cho việc xử lý lỗi diễn ra một cách nhanh chóng
3/ Tạo nên các kiểu lỗi khác nhau được đặt trong các gói tương ứng với từng kiểu lỗi do vậy ta xác định rõ được mã lỗi trả về và dễ dàng xử lý hơn
chương trình minh hoạ

C.Ví dụ minh hoạ xử lý các loại biệt lệ trong tuyến đoạn

1. Xử lý biệt lệ có sẵn trong tuyến đoan.
class Tinhpi{
public static void main (String [] args)
{
MyThread mt = new MyThread ();
mt.start ();

while (mt.isAlive ())
try
{
Thread.sleep (10); // Sleep for 10 milliseconds
}
catch (InterruptedException e)
{
}

System.out.println ("pi = " + mt.pi);
}
}

class MyThread extends Thread
{
boolean negative = true;
double pi; // Initializes to 0.0, by default

public void run ()
{
for (int i = 3; i < 100000; i += 2)
{
if (negative)
pi -= (1.0 / i);
else
pi += (1.0 / i);

negative = !negative;
}

pi += 1.0;

pi *= 4.0;

System.out.println ("Finished calculating PI");
}
}
Kết qủa thực hiện chương trình:
C:\jdk1.3\HocJava>java Tinhpi
Finished calculating PI
pi = 3.1415726535897894
C:\jdk1.3\HocJava>
2.Xử lý biệt lệ tự tạo trong tuyến đoạn
class MyArraySiseException extends NegativeArraySizeException{
MyArraySiseException(){
super(“CANH BAO :loi ban mac phai la kich co cua mang khong hop le”);
}
};

class myException{
int size, array[];

myException(int s) {
size= s;
}

public void run() {
try {
checkSize();
}
catch (MyArraySiseException e) {
System.out.println(e);
}
}
void checkSize() throws MyArraySiseException {
if(size<0) throw new MyArraySiseException();
else System.out.println(“kich co cua mang la dung”);
array = new int[3];
for (int i=0 ;i<3 ;i++ ) array
=i+1;
}

};

class myExceptiontutao{
public static void main(String arg[]) {
myException mt1 = new myException(9);
myException mt1 = new myException(-9);
mt1.start();
mt2.start();
}

};
Kết quả thực hiện chương trình:

C:\jdk1.3\HocJava>java myExceptiontutao
kich co cua mang la dung
MyArraySiseException: CANH BAO :loi ban mac phai la kich co cua mang khong hop
le

C:\jdk1.3\HocJava>

Tài liệu tham khảo


Lập trình Java thế nào (tập 1) Hoàng Ngọc Giao

How to program with threads: An introduction to multithreaded programming

http://www.sun.com/sunworldonline/swol-02-1996/swol-02-threads.html

Using threads in Java http://www.javaworld.com/javaworld/jw-04-1996/jw-04-synch.html

Sun's API documentation on threads http://java.sun.com/JDK-1.0/api/java.lang.Thread.html

Sun's tutorial on threads http://java.sun.com/tutorial/applet/overview/threads.html

Thread monitoring applet -- excellent utility http://www.fsg.com/tech/threadmon.htm

Teach Yourself Java in 21 Days - Currently one of the best books on learning Java

http://www.mcp.com/samsnet/books/tyjava
http://www.javaworld.com/jw-12-1996/jw-12-indepth.html
http://java.sun.com/products/jdk/1.2/docs/guide/collections/index.html

Những cái ôm thật đúng lúc Su Dung Phim Tat Trong Windows

Write a comment

New comments have been disabled for this post.

February 2014
S M T W T F S
January 2014March 2014
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28