Xử lý đa luồng trong Java
Tạo luồng bằng cách kế thừa lớp Thread
package demo;
public class LuongKeThua extends Thread {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("Luồng đang chạy: " + i);
}
}
public static void main(String[] args) {
LuongKeThua luong = new LuongKeThua();
luong.start();
for (int i = 0; i < 3; i++) {
System.out.println("Chạy từ luồng chính: " + i);
}
}
}
Tạo luồng bằng cách thực hiện giao diện Runnable
package demo;
public class LuongRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("Đang chạy từ luồng phụ: " + i);
}
}
public static void main(String[] args) {
Thread luongPhu = new Thread(new LuongRunnable());
luongPhu.start();
for (int i = 0; i < 3; i++) {
System.out.println("Đang chạy từ luồng chính: " + i);
}
}
}
Vấn đề đồng thời khi xử lý tài nguyên chung
package demo;
public class VD_DongThoi implements Runnable {
private int veSo = 5;
@Override
public void run() {
while (veSo > 0) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + " mua vé số: " + veSo--);
}
}
public static void main(String[] args) {
VD_DongThoi veSo = new VD_DongThoi();
new Thread(veSo, "Khách hàng A").start();
new Thread(veSo, "Khách hàng B").start();
}
}
Đua giữa rùa và thỏ
package demo;
public class Duathlao implements Runnable {
private static String thangCuoc;
@Override
public void run() {
for (int buoc = 0; buoc <= 10; buoc++) {
if ("Thỏ".equals(Thread.currentThread().getName()) && buoc % 3 == 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
}
if (gameOver(buoc)) break;
System.out.println(Thread.currentThread().getName() + " chạy bước: " + buoc);
}
}
private boolean gameOver(int buoc) {
if (thangCuoc != null) return true;
if (buoc >= 10) {
thangCuoc = Thread.currentThread().getName();
System.out.println("Người thắng là: " + thangCuoc);
return true;
}
return false;
}
public static void main(String[] args) {
new Thread(new Duathlao(), "Rùa").start();
new Thread(new Duathlao(), "Thỏ").start();
}
}
Sử dụng Callable để trả về kết quả
package demo;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class TinhToanCallable implements Callable<Integer> {
private int soA, soB;
public TinhToanCallable(int a, int b) {
this.soA = a;
this.soB = b;
}
@Override
public Integer call() throws Exception {
return soA + soB;
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService dichVu = Executors.newFixedThreadPool(2);
Future<Integer> ketQua1 = dichVu.submit(new TinhToanCallable(5, 7));
Future<Integer> ketQua2 = dichVu.submit(new TinhToanCallable(10, 20));
System.out.println("Kết quả 1: " + ketQua1.get());
System.out.println("Kết quả 2: " + ketQua2.get());
dichVu.shutdown();
}
}
Dừng luồng an toàn
package demo;
public class DungLuuongAnToan implements Runnable {
private volatile boolean dangChay = true;
@Override
public void run() {
int dem = 0;
while (dangChay) {
System.out.println("Luồng đang chạy lần: " + dem++);
}
}
public void dungLuuong() {
this.dangChay = false;
}
public static void main(String[] args) throws InterruptedException {
DungLuuongAnToan luong = new DungLuuongAnToan();
Thread t = new Thread(luong);
t.start();
Thread.sleep(2000);
luong.dungLuuong();
System.out.println("Dừng luồng.");
}
}
Sleep và join
package demo;
public class SleepJoin {
public static void main(String[] args) throws InterruptedException {
Thread luongVIP = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Luồng VIP chạy: " + i);
}
});
luongVIP.start();
for (int i = 0; i < 5; i++) {
if (i == 2) luongVIP.join();
System.out.println("Luồng chính chạy: " + i);
}
}
}
Quản lý trạng thái luồng
package demo;
public class TrangThaiLuuong {
public static void main(String[] args) throws InterruptedException {
Thread luong = new Thread(() -> {
for (int i = 0; i < 3; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {}
}
});
System.out.println("Trạng thái ban đầu: " + luong.getState());
luong.start();
System.out.println("Sau khi start: " + luong.getState());
while (luong.getState() != Thread.State.TERMINATED) {
Thread.sleep(100);
System.out.println("Cập nhật trạng thái: " + luong.getState());
}
}
}
Ưu tiên luồng
package demo;
public class UuTienLuuong implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " có mức ưu tiên: " + Thread.currentThread().getPriority());
}
public static void main(String[] args) {
Thread luong1 = new Thread(new UuTienLuuong());
Thread luong2 = new Thread(new UuTienLuuong());
luong2.setPriority(Thread.MIN_PRIORITY);
luong1.start();
luong2.start();
}
}
Đồng bộ hóa với synchronized
package demo;
public class DongBoHoa implements Runnable {
private int veSo = 5;
@Override
public synchronized void run() {
while (veSo > 0) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + " mua vé số: " + veSo--);
}
}
public static void main(String[] args) {
DongBoHoa quayVeSo = new DongBoHoa();
new Thread(quayVeSo, "Khách A").start();
new Thread(quayVeSo, "Khách B").start();
}
}
Sử dụng Lock
package demo;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SuDungLock implements Runnable {
private int soLuong = 5;
private final Lock khoa = new ReentrantLock();
@Override
public void run() {
while (soLuong > 0) {
khoa.lock();
try {
if (soLuong > 0) {
Thread.sleep(500);
System.out.println(Thread.currentThread().getName() + " lấy sản phẩm: " + soLuong--);
}
} catch (InterruptedException e) {} finally {
khoa.unlock();
}
}
}
public static void main(String[] args) {
SuDungLock luong = new SuDungLock();
new Thread(luong).start();
new Thread(luong).start();
}
}