TỔNG QUAN
CẤU TRÚC ĐIỀU KHIỂN
VÒNG LẶP
CHUỖI VÀ MẢNG
COLLECTIONS
THƯ VIỆN QUAN TRỌNG
HƯỚNG ĐỐI TƯỢNG
XỬ LÝ LUỒNG
EXCEPTION
LÀM VIỆC VỚI FILE
THAM KHẢO
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Tạo và quản lý luồng trong Java

Trong bài trước, các bạn đã được tìm hiểu về các khái niệm luồng, thế nào là một chương trình đa tiến trình trong Java. Sang bài này, tôi sẽ hướng dẫn các bạn cụ thể về hai cách tạo luồng và các ví dụ minh họa đi kèm.

1. Tạo luồng bằng cách kế thừa từ lớp Thread

Để tạo luồng bằng cách kế thừa từ lớp Thread, chúng ta phải tạo một lớp kế thừa từ lớp Thread. Như đã nói trong bài trước, Thread là một lớp có thể tạo ra 1 lớp chạy đa tiến trình được. Trong ví dụ dưới đây tôi tạo ra một lớp có tên là MyThread kế thừa từ lớp Thread và dĩ nhiên lúc này lớp MyThread sẽ là một lớp có thể tạo luồng được.

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

MyThread.java
package vidu;

public class MyThread extends Thread {

}

Sau đó chúng ta sẽ tiến hành ghi đè phương thức run() của lớp Thread. Những gì có trong phương thức run() này sẽ được thực thi khi luồng bắt đầu chạy. Để ghi đè phương thức này, chúng ta vào Source → Override/Implement Methods, sau đó chọn phương thức run() và nhấn OK để kết thúc. Lúc này lớp MyThread sẽ có nội dung như sau:

Java
package vidu;

public class MyThread extends Thread {

	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
	}

}

Trong phương thức run(), để đơn giản tôi sẽ viết 1 vòng lặp for duyệt i từ 0 đến 4. Mỗi lần chạy sẽ hiển thị tên luồng đang chạy thông qua dòng System.out.println(Thread.currentThread().getName()); với kết quả hiển thị không giống nhau. Tức là luồng trong Java sẽ được chạy dưới dạng bất đồng bộ, chúng ta không biết được luồng nào chạy trước và luồng nào chạy sau (phụ thuộc vào hệ điều hành. Hệ điều hành sẽ quyết định tiến trình nào được chạy trước và với mỗi lần chạy thì kết quả sẽ khác nhau, do đó đối với đa luồng thì chúng ta rất khó sửa lỗi).

MyThread.java
package vidu;

public class MyThread extends Thread {

	@Override
	public void run() {
		super.run();
		for (int i = 0; i < 5; i++) {
			// Thread.currentThread().getName(): cho chúng ta biết tên luồng đang chạy
			// và tên luồng này có thể thay đổi được.
			System.out.println(Thread.currentThread().getName());
		}
	}

}

TestThread.java
package vidu;

public class TestThread {

	public static void main(String[] args) {
		// Tạo ra luồng myThread0 từ lớp MyThread		
		MyThread myThread0 = new MyThread();
		myThread0.start();	// kích hoạt luồng
		
		// Tạo ra luồng myThread1 từ lớp MyThread		
		MyThread myThread1 = new MyThread();
		myThread1.start();
		
		// Tạo ra luồng myThread2 từ lớp MyThread		
		MyThread myThread2 = new MyThread();
		myThread2.setName("Luồng 2");	// thay đổi tên luồng thành Luồng 2
		myThread2.start();
	}

}

Kết quả sau khi biên dịch chương trình:

ketqua vi du tao luong ke thua tu lop Thread PNG

Trong lớp TestThread tôi có dòng code myThread2.setName("Luồng 2");, đây là dòng lệnh dùng để thay đổi tên của luồng myThread2 thành "Luồng 2", mặc định thì tên gọi của mỗi luồng sẽ là Thread-số thứ tự, với số thứ tự của luồng được bắt đầu từ 0.

Lưu ý: Mọi câu lệnh, nhiệm vụ mà chúng ta muốn luồng thực thi thì chúng ta phải khai báo trong phương thức run() (trong ví dụ này thì nhiệm vụ của mỗi luồng là hiển thị tên của luồng đó 5 lần) nhưng nếu chúng ta muốn thực thi luồng đó thì chúng ta phải gọi phương thức start(). Phương thức start() là phương thức dùng để cấp phát tài nguyên cho luồng rồi mới gọi phương thức run() để chạy. Nếu chúng ta không gọi phương thức start() thì những câu lệnh có trong run() sẽ không được chạy.

2. Tạo luồng bằng cách implement Interface Runnable

Để tạo luồng bằng cách implement Interface Runnable, chúng ta phải tạo một lớp implement Interface này. Trong ví dụ dưới đây tôi tạo ra một lớp có tên là DemoThread implement Interface Runnable và dĩ nhiên lúc này lớp DemoThread sẽ là một lớp có thể tạo luồng được.

DemoThread.java
package vidu;

public class DemoThread implements Runnable {

	@Override
	public void run() {
		// TODO Auto-generated method stub

	}

}

Tương tự như khi chúng ta tạo luồng bằng cách kế thừa từ lớp Thread thì khi tạo luồng bằng cách implement Interface Runnable thì chúng ta cũng có phương thức run() và những gì có trong phương thức run() này sẽ được thực thi khi luồng bắt đầu chạy, chỉ khác là khi tạo từ lớp Thread thì chúng ta phải tiến hành override lại phương thức này còn đối với tạo từ Runnable thì phương thức run() này đã được tự động override lại.

Trong phương thức run() của lớp DemoThread chúng ta thêm vào đoạn code như sau:

DemoThread.java
package vidu;

public class DemoThread implements Runnable {

	@Override
	public void run() {
		for (int i = 0; i < 3; i++) {
			// Thread.currentThread().getId(): lấy id của luồng đang chạy
			// nó dùng để phân biệt với các luồng khác cùng tiến trình hoặc cùng tập luồng.
			// Đây là thông số mà máy ảo java tự tạo ra khi ta tạo luồng 
			// nên ta không thể sửa đổi cũng như áp đặt thông số này khi tạo luồng. 
			System.out.println(Thread.currentThread().getId() + "\t" + 
					Thread.currentThread().getName());
		}
	}

}

Main.java
package vidu;

public class Main {

	public static void main(String[] args) {
		DemoThread demoThread0 = new DemoThread();
		Thread thread0 = new Thread(demoThread0);
		thread0.start();
		
		DemoThread demoThread1 = new DemoThread();
		Thread thread1 = new Thread(demoThread1);
		thread1.setName("Luồng 1");
		thread1.start();
		
		DemoThread demoThread2 = new DemoThread();
		Thread thread2 = new Thread(demoThread2);
		thread2.start();
	}

}

Kết quả sau khi biên dịch chương trình:

ketqua vi du tao luong implement Interface Runnable PNG

Chúng ta sẽ sử dụng cách tạo luồng bằng cách implement Interface Runnable khi chúng ta muốn chia sẻ thuộc tính giữa các luồng trong chương trình. Ví dụ dưới đây sé minh họa điều này:

ShareThread.java
package vidu;

public class ShareThread implements Runnable {
	
	private int shareVariable = 0;	// thuộc tính sử dụng chung
	
	public int getShareVariable() {
		return shareVariable;
	}

	@Override
	public void run() {
		for (int i = 0; i < 3; i++) {
			System.out.println("ID:" + Thread.currentThread().getId() + 
					", Name: " + Thread.currentThread().getName()
					+ ", shareVariable = " + shareVariable);
			shareVariable += 2;
		}
	}

}

TestShareThread.java
package vidu;

public class TestShareThread {

	public static void main(String[] args) {
		
		ShareThread shareThread = new ShareThread();
		
		Thread thread0 = new Thread(shareThread);
		thread0.setName("Luồng 1");
		thread0.start();
		
		Thread thread1 = new Thread(shareThread);
		thread1.setName("Luồng 2");
		thread1.start();
		
		Thread thread2 = new Thread(shareThread);
		thread2.setName("Luồng 3");
		thread2.start();
		
		System.out.println("Giá trị thuộc tính shareVariable = " + shareThread.getShareVariable());
	}

}

Kết quả sau khi biên dịch chương trình:

ketqua vi du chia se thuoc tinh giua cac luong PNG

3. Lời kết

Trong bài này tôi đã hướng dẫn các bạn các cách tạo luồng trong Java và ví dụ minh họa. Đây là nội dung chính và quan trọng nhất của chương này. Sang bài sau tôi sẽ trình bày các phần còn lại liên quan đến luồng trong Java. Các bạn theo dõi nhé!

Cùng chuyên mục:

Khi nào dùng Default Methods trong Java 8

Khi nào dùng Default Methods trong Java 8

Ở 2 bài trước chúng ta đã tìm hiểu 2 tính năng mới của Java…

Cách chuyển chữ hoa thành chữ thường trong Java

Cách chuyển chữ hoa thành chữ thường trong Java

Trong bài viết này chúng ta sẽ tìm hiểu về cách chuyển đổi chữ in…

Bài tập tính tổng các số tự nhiên trong Java

Bài tập tính tổng các số tự nhiên trong Java

Các số dương 1, 2, 3, 4, ... được gọi là các số tự nhiên,…

Cách chuyển chữ thường thành chữ hoa trong Java

Cách chuyển chữ thường thành chữ hoa trong Java

Trong chuỗi có thể vừa có ký tự thường vừa có ký tự hoa, nhưng…

Cách viết hoa ký tự đầu tiên trong Java

Cách viết hoa ký tự đầu tiên trong Java

Để hiểu được bài này, các bạn cần có kiến thức căn bản về Java…

Hướng dẫn chuyển đổi giờ phút giây trong Java

Hướng dẫn chuyển đổi giờ phút giây trong Java

Để hiểu được chương trình, các bạn cần có kiến thức cơ bản về Java.…

Cách lấy thời gian hiện tại trong Java

Cách lấy thời gian hiện tại trong Java

Để hiểu được bài viết này, các bạn cần có kiến thức cơ bản sau…

Cách làm tròn số trong Java

Cách làm tròn số trong Java

Khi thực hiện tính toán, việc kết quả ra một con số thập phân dài…

Cách tìm ma trận chuyển vị trong Java

Cách tìm ma trận chuyển vị trong Java

Quá trình hoán đổi giữa hàng và cột được gọi là chuyển vị của ma…

Cách chuyển ArrayList thành mảng và ngược lại trong Java

Cách chuyển ArrayList thành mảng và ngược lại trong Java

Để hiểu được bài này, các bạn cần có kiến thức cơ bản về mảng…

Cách nối hai mảng trong Java

Cách nối hai mảng trong Java

Mình sẽ thực hiện hai chương trình nối mảng. Chương trình thứ nhất nối hai…

Cách xóa khoảng trắng của chuỗi trong Java

Cách xóa khoảng trắng của chuỗi trong Java

Mình sẽ thực hiện hai chương trình khác nhau để các bạn có thể hiểu…

In ra tam giác bằng ký tự * và số trong Java

In ra tam giác bằng ký tự * và số trong Java

Mình sẽ giới thiệu cách để in ra các tam giác bằng ký tự *…

Tìm số lớn nhất trong mảng Java

Tìm số lớn nhất trong mảng Java

Các bạn cần tìm hiểu về mảng, cách khởi tạo và in mảng trong Java…

Tìm ước của một số nguyên trong Java

Tìm ước của một số nguyên trong Java

Trong bài viết này chúng ta sẽ tìm hiểu cách tìm tất cả các ước…

Cách kiểm tra số hoàn hảo trong Java

Cách kiểm tra số hoàn hảo trong Java

Cách kiểm tra số đối xứng trong Java

Cách kiểm tra số đối xứng trong Java

Trong bài viết này chúng ta sẽ kiểm tra một số có phải là số…

Đảo ngược một số trong Java

Đảo ngược một số trong Java

Mình sẽ giới thiệu các bạn cách đảo ngược một số sử dụng vòng lặp…

Tìm bội chung nhỏ nhất trong Java

Tìm bội chung nhỏ nhất trong Java

Mình sẽ sử dụng hai cách khác nhau để tìm BCNN. Cách thứ nhất mình…

Cách hoán đổi hai số trong Java

Cách hoán đổi hai số trong Java

Trong phần này mình sẽ sử dụng một biến tạm temp() làm biến trung gian…

Top