Các trạng thái của luồng

Một phần của tài liệu Đề tài khoa học - Tìm hiểu cơ chế phân luồng trong các chương trình java - Học viện Kỹ thuật Mật mã (Trang 33 - 38)

- Một luồng nhân chỉ có một cấu trúc dữ liệu nhân và ngăn xếp Cấu trúc dữ liệu

Phần 3: Luồng trong java 2.1 Khái niệm luồng trong java

2.5 Các trạng thái của luồng

New Thread: Đây là trạng thái khi luồng vừa được khởi tạo bằng phương thức khởi tạo của lớp Thread nhưng chưa được start(). Ở trạng thái này, luồng được tạo ra nhưng chưa được cấp phát tài nguyên và cũng chưa chạy. Nếu luồng đang ở trạng thái này mà ta gọi các phương thức ép buộc stop,resume,suspend … sẽ là nguyên nhân sảy ra ngoại lệ IllegalThreadStateException

VD:

Thread test=new Thread();

Lúc này thread test đang ở trạng thái New Thread và chưa được cấp phát tài nguyên.

Runnable: Xét đoạn mã sau: PHP Code:

Thread test=new Thread();

test.start();

Sau khi gọi phương thức start() thì luồng test đã được cấp phát tài nguyên và các lịch điều phối CPU cho luồng test cũng bắt đầu có hiệu lực. Ở đây, chúng ta dùng trạng thái là Runnable chứ không phải Running, vì như đã nói ở phần đầu (Các mô hình đa luồng) thì luồng không thực sự luôn chạy mà tùy vào hệ thống mà có sự điều phối CPU khác nhau.

Ví dụ: Trong HĐH đa nhiệm nhưng chỉ có 1 bộ xử lý (CPU) thì không phải tất cả các tiến trình, các luồng đều được cùng chạy song song mà chúng được luân phiên nhau chạy định kỳ trong 1 thời gian nhất định, sau đó phải tạm ngưng và trả CPU về cho HĐH, HĐH lại cấp CPU này cho luồng khác chạy trong 1 khoảng nhất định ….

Như vậy: Tuy luồng đang ở trạng thái Runnable nhưng không phải luồng luôn đang chạy nên không thể gọi là Running. Tuy nhiên để đơn giản vấn đề, chúng ta có thể tạm coi trạng thái này là luồng đang “chạy” tuy rằng điều này không chính

xác 100%.

Luồng sẽ ở trạng thái Runnable này từ khi luồng được gọi phương thức start() và trước khi luồng kết thúc các công việc trong phương thức run() hoặc trước khi sảy ra 1 ngoại lệ nào đó trong run() khiến run() bị kết thúc. Một dố trường hợp nếu ta tự ý stop() hoặc destroy() luồng thì cũng khiến luồng rời khỏi trạng thái runnable

Not Runnable:

Một luồng bị rơi vào trạng thái “Not Runable” thì do 1 trong bốn nguyên nhân sau: + Luồng bị tạm ngưng 1 khoảng nhất định do bị gọi phương thức sleep(long

milisecond)

+ Luồng bị tạm ngưng cấp CPU do bị gọi phương thức suspend()

+ Luồng bị gọi phương thức wait() để tạm ngưng để chờ 1 điều kiện nào đó thay đổi khác với hiện tại. VD: chờ tài nguyên (Xem tiếp phần Đồng bộ hóa)

+ Luồng đang bị Block vì phải chờ I/O. Ví dụ: trong lúc chờ người dùng nhập dữ liệu vào bàn phím, luồng bị Block

Ví dụ: PHP Code: try { Thread.sleep(10000); } catch (InterruptedException e){ }

Trong ví dụ trên, luồng sẽ tạm ngưng làm việc trong suốt 10000 mili giây (10 giây). Tuy nhiên, cần lưu ý 1 điều là: khác với suspend(), khi sleep() luồng vẫn

được cấp CPU, nhưng luồng không làm gì cả, còn suspend() luồng sẽ bị ngưng cấp CPU. Ngoài ra, cũng có 1 điều lưu ý khác : Luồng bị “Not Runnable” bởi nguyên nhân nào thì phải cho luồng chạy lại bởi 1 tác động thích hợp với đúng nguyên nhân đó. Cụ thể như sau:

+ Nếu luồng bị Sleep, phải đợi cho đến khi hết thời gian chỉ định sleep thì luồng sẽ tự chạy lại

+ Nếu luồng bị suspend() ta phải gọi phương thức resume() để tiếp tục lại

+ Nếu luồng đang wait() , tức là chờ đợi 1 điều kiện nào đó thì luồng sở hữu điều kiện đó phải gọi phương thức notify() hoặc notifyall() để thông báo cho luồng chạy lại

+ Nếu luồng đang bị Block vì I/O thì quá trình I/O phải được hoàn tất

Như vậy, nếu luồng bị sleep 10 giây, mà nếu mới trải qua 5 giây, dù ta có gọi phương thức resume() thì luồng vẫn không thể chạy lại mà sẽ xảy ra ngoại lệ (Sẽ đề cập các ngoại lệ sâu hơn ở phần sau)

Dead:

Một thread bị rơi vào trạng thái Dead do 1 trong 2 cách: Chết tự nhiên hoặc bị ép dừng lại. Ví dụ dưới, phương thức run() bao gồm 1 vòng lặp hữu hạn, Nó sẽ lặp đi lặp lại 100 lần rồi thoát.

PHP Code:

public void run() { int i = 0;

while (i < 100) { i++;

} }

Một thread sẽ chết 1 cách tự nhiên khi nó hoàn thành các lệnh trong phương thức run().

Bạn cũng có thể kết thúc 1 luồng bất kỳ lúc nào bằng cách gọi phương thức stop(). Đoạn mã sau đặt luồng vào trạng thái sleep 10s, sau khi luồng “thức dậy” sẽ bị stop()

PHP Code:

Thread myThread = new MyThreadClass();

myThread.start(); try { Thread.sleep(10000); } catch (InterruptedException e){ } myThread.stop();

Phương thức stop() ném ra 1 ngoại lệ ThreadDeath để “giết” luồng này. Vì vậy, các luồng này sẽ “chết” không đồng bộ. Các luồng sẽ “chết” khi nó nhận được 1 ngoại lệ ThreadDeath.

Phương thức stop() sẽ làm phương thức run() kết thúc đột ngột, đây không phải là 1 cách hay để kết thúc 1 luồng và bị SUN xem là nguy hiểm (Mình sẽ đề cập kỹ hơn ở phần Đồng bộ hóa sắp tới). Mình cũng sẽ đề xuất 1 phương pháp kết thúc luồng tốt hơn ở các phần sau.

Một phần của tài liệu Đề tài khoa học - Tìm hiểu cơ chế phân luồng trong các chương trình java - Học viện Kỹ thuật Mật mã (Trang 33 - 38)

Tải bản đầy đủ (DOCX)

(44 trang)
w