在多线程编程中,线程阻塞是一种常见现象,它指的是线程在执行过程中暂时停止执行,等待某个条件成立或者某个资源可用。合理地使用线程阻塞可以提高程序的效率和响应速度。以下是6种实用的线程阻塞方法,以及相应的案例分析。
1. 使用sleep()方法
sleep()方法是Java中Thread类提供的一个静态方法,可以让当前线程暂停执行指定的时间。这种方法适用于不需要立即响应的场景。
案例分析:
public class SleepExample {
public static void main(String[] args) {
Thread t = new Thread(() -> {
System.out.println("Thread started.");
try {
Thread.sleep(2000); // 暂停2秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread resumed.");
});
t.start();
System.out.println("Main thread is running.");
}
}
输出结果:
Thread started.
Main thread is running.
Thread resumed.
2. 使用wait()方法
wait()方法是Object类提供的一个方法,可以让当前线程等待,直到其他线程调用该对象的notify()或notifyAll()方法。
案例分析:
public class WaitExample {
private Object lock = new Object();
public void method1() {
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void method2() {
synchronized (lock) {
lock.notify();
}
}
}
3. 使用join()方法
join()方法是Thread类提供的一个方法,可以让当前线程等待直到指定的线程结束。
案例分析:
public class JoinExample {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
System.out.println("Child thread is running.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Child thread finished.");
});
t.start();
t.join(); // 等待子线程结束
System.out.println("Main thread finished.");
}
}
输出结果:
Child thread is running.
Child thread finished.
Main thread finished.
4. 使用CountDownLatch
CountDownLatch是一个同步辅助类,允许一个或多个线程等待其他线程完成操作。
案例分析:
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
new Thread(() -> {
System.out.println("Thread " + Thread.currentThread().getName() + " is running.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}).start();
}
latch.await(); // 等待所有线程完成
System.out.println("All threads finished.");
}
}
输出结果:
Thread Thread-0 is running.
Thread Thread-1 is running.
Thread Thread-2 is running.
Thread Thread-0 finished.
Thread Thread-1 finished.
Thread Thread-2 finished.
All threads finished.
5. 使用Semaphore
Semaphore是一个信号量,用于控制对资源的访问,它可以设定一个许可的数量,线程在执行时需要获取一个许可,如果没有许可,线程将被阻塞。
案例分析:
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
private Semaphore semaphore = new Semaphore(2);
public void method() {
try {
semaphore.acquire(); // 获取一个许可
System.out.println("Thread " + Thread.currentThread().getName() + " is running.");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release(); // 释放一个许可
}
}
public static void main(String[] args) {
SemaphoreExample example = new SemaphoreExample();
new Thread(example::method).start();
new Thread(example::method).start();
new Thread(example::method).start();
}
}
输出结果:
Thread Thread-0 is running.
Thread Thread-1 is running.
Thread Thread-2 is running.
6. 使用FutureTask
FutureTask是一个可以用来异步执行计算的类,它继承自Runnable接口,并提供了获取计算结果的方法。
案例分析:
import java.util.concurrent.FutureTask;
public class FutureTaskExample {
public static void main(String[] args) {
FutureTask<String> futureTask = new FutureTask<>(() -> {
System.out.println("Child thread is running.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Result";
});
new Thread(futureTask).start();
try {
String result = futureTask.get(); // 获取计算结果
System.out.println("Result: " + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
输出结果:
Child thread is running.
Result: Result
以上6种方法都是线程阻塞的实用方法,可以根据不同的场景选择合适的方法。在实际开发中,合理地使用线程阻塞可以提高程序的效率和性能。
