在Java中,唤醒多线程通常涉及到线程间的通信和协作,以下是几种常见的方法:
使用wait()和notifyAll()方法
当一个线程需要等待另一个线程的信号时,可以调用`wait()`方法进入等待状态。
当另一个线程完成某些操作并希望唤醒等待的线程时,可以调用`notifyAll()`方法,这将唤醒所有正在等待的线程。
示例代码:
class TestWait extends Thread {
String name;
public TestWait(String name) {
super(name);
this.name = name;
}
public synchronized void run() {
for (int i = 0; i < 5; i++) {
if (i == 4) {
try {
this.wait(); // 进入等待状态
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " 执行 " + i);
}
}
}
public class Main {
public static void main(String[] args) {
TestWait t = new TestWait("线程1");
TestWait t1 = new TestWait("线程2");
t.start();
t1.start();
}
}
使用条件变量(如`Condition`)
`Condition`接口提供了线程间的条件变量同步,允许一个或多个线程等待某个条件成立。
`Condition`对象通常与`Lock`接口一起使用,提供比`wait()`和`notifyAll()`更灵活的线程同步机制。
示例代码:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class TestCondition extends Thread {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void run() {
lock.lock();
try {
while (!condition.await(10, TimeUnit.SECONDS)) { // 等待10秒
System.out.println(Thread.currentThread().getName() + " 等待条件成立");
}
System.out.println(Thread.currentThread().getName() + " 条件成立,继续执行");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class Main {
public static void main(String[] args) {
TestCondition tc = new TestCondition();
tc.start();
// 模拟某些操作,在10秒后改变条件
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
tc.condition.signalAll(); // 唤醒所有等待的线程
}
}
使用信号量(Semaphore)
`Semaphore`是一个计数信号量,可以用来控制对共享资源的访问。
当一个线程想要访问资源时,它会尝试获取信号量;如果信号量的计数大于0,则线程可以继续执行,并将信号量的计数减1;否则,线程将被阻塞,直到其他线程释放信号量。
示例代码:
import java.util.concurrent.Semaphore;
class TestSemaphore extends Thread {
private Semaphore semaphore = new Semaphore(1);
public void run() {
try {
semaphore.acquire(); // 获取信号量
System.out.println(Thread.currentThread().getName() + " 获取到信号量,执行任务");
// 执行任务
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release(); // 释放信号量
}
}
}
public class Main {
public static void main(String[] args) {
TestSemaphore ts = new TestSemaphore();
ts.start();
ts.start(); // 第二个线程将阻塞,直到第一个线程释放信号量
}
}
以上方法都可以用来在Java中唤醒多线程,具体使用哪种方法取决于你的应用场景和需求。请选择最适合你场景的方法来实现线程间的同步和通信