Đa luồng trong Java

Java là một ngôn ngữ lập trình đa luồng có nghĩa là chúng ta có thể phát triển các chương trình đa luồng sử dụng Java. Một chương trình đa luồng chứa hai hoặc nhiều bộ phận có thể chạy đồng thời và mỗi một phần có thể xử lý các nhiệm vụ khác nhau cùng một lúc làm việc sử dụng tối ưu các nguồn lực sẵn đặc biệt khi máy tính của bạn có nhiều CPU.
Theo định nghĩa đa nhiệm là khi nhiều tiến trình chia sẻ tài nguyên xử lý thông thường như một CPU. Multithreading mở rộng ý tưởng của đa nhiệm vào các ứng dụng mà bạn có thể chia nhỏ các hoạt động cụ thể trong một ứng dụng duy nhất vào chủ đề cá nhân. Mỗi chủ đề có thể chạy song song. Các hệ điều hành chia thời gian xử lý không chỉ giữa các ứng dụng khác nhau, nhưng cũng trong mỗi chủ đề trong một ứng dụng.
Multithreading cho phép bạn viết trong một cách mà nhiều hoạt động có thể tiến hành đồng thời trong cùng một chương trình.

Life Cycle of a Thread:

Thread đi qua các giai đoạn khác nhau trong vòng đời của nó. Ví dụ, một chủ đề được sinh ra, bắt đầu, chạy, và sau đó chết. Biểu đồ sau cho thấy vòng đời hoàn chỉnh của một chủ đề.
Java Thread
Giai đoạn nói trên được giải thích ở đây:
  • New: Một chủ đề mới bắt đầu chu kỳ sống của nó trong trạng thái mới. Nó vẫn còn trong trạng thái này cho đến khi chương trình bắt đầu thread. Nó cũng được gọi là thread sinh ra.
  • Runnable: Sau khi một thread mới được sinh ra là bắt đầu, các chủ đề trở nên Runnable. Một chủ đề ở trạng thái này được coi là thực hiện nhiệm vụ của mình.
  • Waiting: Đôi khi, một chủ đề chuyển sang trạng thái chờ đợi trong khi thread đợi cho thread khác để thực hiện một quá trình chuyển đổi task.A chủ đề trở lại trạng thái Runnable chỉ khi một sợi tín hiệu sợi chờ đợi để tiếp tục thực hiện.
  • Timed waiting: Một chủ đề Runnable thể vào trạng thái chờ đợi hẹn giờ cho một khoảng thời gian xác định thời gian. Một chủ đề trong trạng thái này chuyển tiếp trở về trạng thái Runnable khi mà khoảng thời gian hết hạn hoặc khi sự kiện đó đang chờ đợi xảy ra.
  • Terminated: Một chủ đề Runnable vào trạng thái chấm dứt khi nó hoàn thành nhiệm vụ của mình hoặc nếu không chấm dứt.

Mức độ ưu tiên Thread:

Mỗi chủ đề Java có một ưu tiên hỗ trợ hệ điều hành xác định thứ tự mà trong đó chủ đề được lên kế hoạch.
Ưu tiên thread Java nằm trong khoảng giữa MIN_PRIORITY (một hằng số 1) và MAX_PRIORITY (một hằng số của 10). Theo mặc định, tất cả các chủ đề được đưa ra NORM_PRIORITY ưu tiên (một hằng số 5).
Chủ đề ưu tiên cao hơn là quan trọng hơn đối với một chương trình và cần được phân bổ thời gian xử lý trước khi đề ưu tiên thấp hơn. Tuy nhiên, ưu tiên những chủ đề không thể đảm bảo trật tự, trong đó đề thi và rất nhiều nền tảng dependentant.

Tạo  Thread bằng cách Implementing Runnable Interface:

Nếu class của bạn dự định sẽ được thực hiện như một sợi sau đó bạn có thể đạt được điều này bởi giao diện implementingRunnable. Bạn sẽ cần phải làm theo ba bước cơ bản:

Bước 1:

Như là một bước đầu tiên bạn cần phải thực hiện một phương pháp run () được cung cấp bởi giao diện Runnable. Phương pháp này cung cấp điểm khởi đầu cho các chủ đề và bạn sẽ đưa bạn hoàn toàn logic kinh doanh bên trong phương pháp này. Sau đây là cú pháp đơn giản chạy () phương pháp:
public void run( );

Bước 2:

Tại bước thứ hai bạn sẽ nhanh chóng một Thread object sử dụng constructor sau đây:
Thread(Runnable threadObj, String threadName);
Trường hợp, threadObj là một thể hiện của một lớp mà thực hiện các giao diện Runnable và threadName là tên được đặt cho các chủ đề mới.

Bước 3

Sau khi đối tượng được tạo ra THREAD, bạn có thể bắt đầu bằng cách gọi phương thức start (), mà thực hiện một cuộc gọi để chạy () phương pháp. Sau đây là cú pháp đơn giản của start () phương pháp:
void start( );

VÍ DỤ:

Dưới đây là một ví dụ tạo ra một chủ đề mới và bắt đầu nó chạy:
class RunnableDemo implements Runnable {
private Thread t;
private String threadName;

RunnableDemo( String name){
threadName
= name;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
try {
for(int i = 4; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}

public void start ()
{
System.out.println("Starting " + threadName );
if (t == null)
{
t
= new Thread (this, threadName);
t
.start ();
}
}

}

public class TestThread {
public static void main(String args[]) {

RunnableDemo R1 = new RunnableDemo( "Thread-1");
R1
.start();

RunnableDemo R2 = new RunnableDemo( "Thread-2");
R2
.start();
}
}
Điều này sẽ tạo ra các kết quả sau đây:
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.

Tạo Thread bằng cách Extends Thread Class:

Cách thứ hai để tạo ra một sợi là tạo ra một lớp mới mà mở rộng lớp chủ đề bằng cách sử dụng hai bước đơn giản sau đây. Cách tiếp cận này cung cấp sự linh hoạt hơn trong việc xử lý nhiều luồng được tạo ra bằng cách sử dụng phương pháp có sẵn trong lớp Thread.

Bước 1

Bạn sẽ cần phải ghi đè run () phương pháp có sẵn trong lớp Thread. Phương pháp này cung cấp điểm khởi đầu cho các chủ đề và bạn sẽ đưa bạn hoàn toàn logic kinh doanh bên trong phương pháp này. Sau đây là cú pháp đơn giản run () phương pháp:
public void run( );

Bước 2

Sau khi đối tượng được tạo ra chủ đề, bạn có thể bắt đầu bằng cách gọi phương thức start (), mà thực hiện một cuộc gọi để chạy () phương pháp. Sau đây là cú pháp đơn giản của start () phương pháp:
void start( );

Ví dụ:

Dưới đây là các chương trình trước đó viết lại để extends Thread:
class ThreadDemo extends Thread {
private Thread t;
private String threadName;

ThreadDemo( String name){
threadName
= name;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
try {
for(int i = 4; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}

public void start ()
{
System.out.println("Starting " + threadName );
if (t == null)
{
t
= new Thread (this, threadName);
t
.start ();
}
}

}

public class TestThread {
public static void main(String args[]) {

ThreadDemo T1 = new ThreadDemo( "Thread-1");
T1
.start();

ThreadDemo T2 = new ThreadDemo( "Thread-2");
T2
.start();
}
}
Điều này sẽ tạo ra các kết quả sau đây:
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.

Thread Methods:

Sau đây là danh sách các phương pháp quan trọng trong các lớp Thread.
TTCÁC PHƯƠNG PHÁP VỚI MÔ TẢ
1public void start()
Bắt đầu các thread trong một con đường riêng biệt thực hiện, sau đó gọi run ( ) phương thức trên đối tượng chủ đề này .
2public void run()
Nếu đối tượng của đề tài này đã được khởi tạo bằng cách sử dụng một mục tiêu riêng biệt Runnable , run ( ) được gọi trên đối tượng Runnable .
3public final void setName(String name)
Thay đổi tên của đối tượng Thread. Ngoài ra còn có một phương thức getName () để lấy tên.
4public final void setPriority(int priority)
Thiết lập các ưu tiên của đối tượng đề này. Các giá trị có thể là từ 1 đến 10.
5public final void setDaemon(boolean on)
Một thông số của sự thật biểu đề này như một daemon thread.
6public final void join(long millisec)
Các chủ đề hiện gọi phương pháp này trên một sợi thứ hai, gây ra các chủ đề hiện tại để chặn cho đến khi tiểu trình thứ hai kết thúc hoặc số quy định của mili giây trôi qua.
7public void interrupt()
Ngắt lời chủ đề này, gây ra nó để tiếp tục thực hiện nếu nó đã bị chặn vì lý do nào.
8public final boolean isAlive()
Trả về true nếu thread là còn sống, đó là bất cứ lúc nào sau khi đề tài đã được bắt đầu nhưng trước khi nó chạy đến khi hoàn thành.
Các phương pháp trước đó được gọi vào một đối tượng Thread cụ thể. Các phương pháp sau đây trong lớp Thread là tĩnh. Gọi một trong những phương pháp tĩnh thực hiện các hoạt động trên thread đang chạy.
TTCÁC PHƯƠNG THỨC VÀ MÔ TẢ
1public static void yield()
Nguyên nhân các chủ đề hiện đang chạy để mang lại cho bất kỳ chủ đề khác cùng độ ưu tiên đang chờ để được lên kế hoạch.
2public static void sleep(long millisec)
Nguyên nhân các chủ đề hiện đang chạy để chặn ít nhất số quy định của mili giây.
3public static boolean holdsLock(Object x)
Trả về true nếu tiểu trình hiện giữ khóa trên các đối tượng nhất định.
4public static Thread currentThread()
Trả về một tham chiếu đến các chủ đề hiện đang chạy, đó là chủ đề đó gọi phương pháp này.
5public static void dumpStack()
Trả về an reference to the chủ đề hiện đang chạy, which là chủ đề then gọi phương pháp này.

Ví dụ:

Các chương trình ThreadClassDemo sau đây chứng minh một số trong những phương pháp của lớpThread. Hãy xem xét một lớp DisplayMessage which implements Runnable:
// File Name : DisplayMessage.java
// Create a thread to implement Runnable
public class DisplayMessage implements Runnable
{
private String message;
public DisplayMessage(String message)
{
this.message = message;
}
public void run()
{
while(true)
{
System.out.println(message);
}
}
}
Sau đây là một lớp học kéo dài lớp Thread:
// File Name : GuessANumber.java
// Create a thread to extentd Thread
public class GuessANumber extends Thread
{
private int number;
public GuessANumber(int number)
{
this.number = number;
}
public void run()
{
int counter = 0;
int guess = 0;
do
{
guess
= (int) (Math.random() * 100 + 1);
System.out.println(this.getName()
+ " guesses " + guess);
counter
++;
}while(guess != number);
System.out.println("** Correct! " + this.getName()
+ " in " + counter + " guesses.**");
}
}
Sau đây là các chương trình chính mà làm cho sử dụng trên lớp được định nghĩa:
// File Name : ThreadClassDemo.java
public class ThreadClassDemo
{
public static void main(String [] args)
{
Runnable hello = new DisplayMessage("Hello");
Thread thread1 = new Thread(hello);
thread1
.setDaemon(true);
thread1
.setName("hello");
System.out.println("Starting hello thread...");
thread1
.start();

Runnable bye = new DisplayMessage("Goodbye");
Thread thread2 = new Thread(bye);
thread2
.setPriority(Thread.MIN_PRIORITY);
thread2
.setDaemon(true);
System.out.println("Starting goodbye thread...");
thread2
.start();

System.out.println("Starting thread3...");
Thread thread3 = new GuessANumber(27);
thread3
.start();
try
{
thread3
.join();
}catch(InterruptedException e)
{
System.out.println("Thread interrupted.");
}
System.out.println("Starting thread4...");
Thread thread4 = new GuessANumber(75);

thread4
.start();
System.out.println("main() is ending...");
}
}
Điều này sẽ tạo ra các kết quả sau đây. Bạn có thể thử ví dụ này một lần nữa và một lần nữa và bạn sẽ nhận được kết quả khác nhau mỗi lần.
Starting hello thread...
Starting goodbye thread...
Hello
Hello
Hello
Hello
Hello
Hello
Goodbye
Goodbye
Goodbye
Goodbye
Goodbye
.......

Nhận xét