Mức Ưu Tiên Của Luồng
(Thread Priority)

Mỗi luồng trong Java đều có một độ ưu tiên. Độ ưu tiên được biểu diễn bằng một số trong khoảng từ 1 đến 10. Trong hầu hết các trường hợp, bộ lập lịch luồng sắp xếp các luồng theo độ ưu tiên của chúng (được gọi là lập lịch giành quyền - preemptive scheduling). Tuy nhiên, điều này không được đảm bảo vì nó phụ thuộc vào đặc tả của JVM mà bộ lập lịch chọn. Lưu ý rằng không chỉ JVM mà lập trình viên Java cũng có thể gán độ ưu tiên cho các luồng một cách rõ ràng trong chương trình Java.

Phương thức Getter & Setter độ ưu tiên của luồng (Thread Priority)

↳ int getPriority(): Phương thức java.lang.Thread.getPriority() trả về độ ưu tiên của luồng được chỉ định.

↳ void setPriority(int newPriority): Phương thức java.lang.Thread.setPriority() cập nhật hoặc gán độ ưu tiên của luồng thành newPriority. Phương thức này ném ngoại lệ IllegalArgumentException nếu giá trị newPriority vượt ngoài phạm vi, tức là từ 1 (tối thiểu) đến 10 (tối đa).

Ba hằng số được định nghĩa trong lớp Thread:

↳ static int MIN_PRIORITY: Độ ưu tiên tối thiểu, giá trị là 1.

↳ static int NORM_PRIORITY: Độ ưu tiên mặc định, giá trị là 5.

↳ static int MAX_PRIORITY: Độ ưu tiên tối đa, giá trị là 10.

Mặc định, độ ưu tiên của một luồng là 5 (NORM_PRIORITY). Giá trị của MIN_PRIORITY là 1 và giá trị của MAX_PRIORITY là 10.

Ví dụ 1

Dưới đây là một ví dụ về cách sử dụng mức ưu tiên của luồng (Thread Priority) trong Java. Chương trình này tạo ra ba luồng với các mức ưu tiên khác nhau và cho thấy cách các luồng được thực thi dựa trên mức ưu tiên của chúng.

Ví dụ: Example.java

class MyThread extends Thread {
    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            System.out.println(getName() + " đang chạy với mức ưu tiên: " + getPriority());
        }
    }
}

public class Example {
    public static void main(String[] args) {
        // Tạo ba luồng với các mức ưu tiên khác nhau
        MyThread thread1 = new MyThread("Luồng 1");
        MyThread thread2 = new MyThread("Luồng 2");
        MyThread thread3 = new MyThread("Luồng 3");

        // Đặt mức ưu tiên cho các luồng
        thread1.setPriority(Thread.MIN_PRIORITY); // Mức ưu tiên thấp nhất
        thread2.setPriority(Thread.NORM_PRIORITY); // Mức ưu tiên bình thường
        thread3.setPriority(Thread.MAX_PRIORITY); // Mức ưu tiên cao nhất

        // Bắt đầu các luồng
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

Kết quả mong đợi:

↳ Luồng 3 (mức ưu tiên cao nhất) có thể sẽ được thực thi trước và nhiều lần hơn so với các luồng khác.

↳ Luồng 1 (mức ưu tiên thấp nhất) có thể sẽ được thực thi ít hơn và có thể chạy sau cùng.

↳ Luồng 2 (mức ưu tiên bình thường) sẽ nằm ở giữa, có thể sẽ chạy sau Luồng 3 và trước Luồng 1.

Kết quả đầu ra có thể khác nhau tùy vào cách hệ điều hành lập lịch các luồng, nhưng nhìn chung, các luồng có mức ưu tiên cao hơn sẽ có khả năng chạy trước.

Kết quả của chương trình là

Luồng 3 đang chạy với mức ưu tiên: 10
Luồng 3 đang chạy với mức ưu tiên: 10
Luồng 3 đang chạy với mức ưu tiên: 10
Luồng 2 đang chạy với mức ưu tiên: 5
Luồng 2 đang chạy với mức ưu tiên: 5
Luồng 2 đang chạy với mức ưu tiên: 5
Luồng 1 đang chạy với mức ưu tiên: 1
Luồng 1 đang chạy với mức ưu tiên: 1
Luồng 1 đang chạy với mức ưu tiên: 1

Lưu ý:

Mức ưu tiên không đảm bảo tuyệt đối về thứ tự thực thi giữa các luồng, nó chỉ giúp hướng dẫn Thread Scheduler. Một số hệ điều hành hoặc JVM có thể không hoàn toàn tuân theo mức ưu tiên mà sẽ phụ thuộc vào việc lập lịch của hệ điều hành.

Ví dụ 2

Dưới đây là một ví dụ về hai luồng trong Java có cùng mức độ ưu tiên được thiết lập bằng phương thức setPriority(int newPriority). Chương trình này sẽ tạo ra hai luồng có cùng mức ưu tiên và hiển thị cách chúng thực thi:

Ví dụ: Example.java

class MyThread extends Thread {
    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 2; i++) {
            System.out.println(getName() + " đang chạy.");
        }
    }
}

public class Example {
    public static void main(String[] args) {
        // Tạo hai luồng với cùng mức ưu tiên
        MyThread thread1 = new MyThread("Luồng 1");
        MyThread thread2 = new MyThread("Luồng 2");

        // Đặt mức ưu tiên cho cả hai luồng
        thread1.setPriority(5); // Mức ưu tiên bình thường (5)
        thread2.setPriority(5); // Mức ưu tiên bình thường (5)

        // Bắt đầu cả hai luồng
        thread1.start();
        thread2.start();
    }
}

Kết quả của chương trình là

Luồng 1 đang chạy.
Luồng 1 đang chạy.
Luồng 2 đang chạy.
Luồng 2 đang chạy.

Lưu ý:

Kết quả có thể thay đổi mỗi khi bạn chạy chương trình vì hai luồng có cùng mức ưu tiên và không có yếu tố nào đảm bảo thứ tự thực thi tuyệt đối giữa chúng. Thread Scheduler sẽ quyết định dựa trên nhiều yếu tố khác nhau như trạng thái hệ thống, môi trường chạy, và chính sách lập lịch của hệ điều hành hoặc JVM.

Ví dụ 3

Trong Java, mức độ ưu tiên của luồng được định nghĩa bởi các hằng số trong lớp Thread, với giá trị từ Thread.MIN_PRIORITY (1) đến Thread.MAX_PRIORITY (10). Giá trị hợp lệ của mức độ ưu tiên nằm trong khoảng từ 1 đến 10. Nếu bạn cố gắng đặt mức độ ưu tiên ra ngoài phạm vi này, hệ thống sẽ không chấp nhận giá trị đó và thường sẽ tự động điều chỉnh về mức giá trị hợp lệ gần nhất, hoặc có thể gây ra một ngoại lệ.

Ví dụ: Example.java

class MyThread extends Thread {
    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        System.out.println(getName() + " với mức ưu tiên: " + getPriority() + " đang chạy.");
    }
}

public class Example {
    public static void main(String[] args) {
        // Tạo hai luồng
        MyThread thread1 = new MyThread("Luồng 1");
        MyThread thread2 = new MyThread("Luồng 2");

        // Đặt mức ưu tiên cho cả hai luồng
        // Mức ưu tiên không hợp lệ
        thread1.setPriority(15); // Mức ưu tiên quá cao
        thread2.setPriority(-5); // Mức ưu tiên quá thấp

        // Kiểm tra mức ưu tiên thực tế
        System.out.println("Mức ưu tiên của Luồng 1: " + thread1.getPriority());
        System.out.println("Mức ưu tiên của Luồng 2: " + thread2.getPriority());

        // Bắt đầu các luồng
        thread1.start();
        thread2.start();
    }
}

Kết quả của chương trình là

Exception in thread "main" java.lang.IllegalArgumentException at java.base/java.lang.Thread.setPriority(Thread.java:1868) at Example.main(Example.java:20)

Hy vọng rằng qua các ví dụ trên, bạn sẽ hiểu rõ hơn về mức độ ưu tiên của luồng trong Java.

Câu Nói Truyền Cảm Hứng

“Bắt đầu ở đâu không quan trọng, quan trọng là bạn sẵn sàng bắt đầu.” – W. Clement Stone

Không Gian Tích Cực

“Chúc bạn luôn giữ vững niềm tin và sức mạnh để vượt qua mọi thử thách trong cuộc sống.”