在 Java 中,线程间通信(Inter-thread Communication)主要用于线程之间共享数据或协调它们的执行。以下是一些常用的线程间通信方式:
wait()
、notify()
和 notifyAll()
方法这些方法属于 Object
类,用于在同步块或同步方法中实现线程间的等待/通知机制。
wait()
:使当前线程进入等待状态,直到其他线程调用 notify()
或 notifyAll()
。notify()
:唤醒一个等待线程。notifyAll()
:唤醒所有等待线程。示例代码:
class SharedResource {
private int value;
private boolean available = false;
public synchronized void produce(int newValue) {
while (available) {
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
value = newValue;
available = true;
notify();
}
public synchronized int consume() {
while (!available) {
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
available = false;
notify();
return value;
}
}
public class WaitNotifyDemo {
public static void main(String[] args) {
SharedResource sharedResource = new SharedResource();
Thread producer = new Thread(() -> {
for (int i = 0; i < 5; i++) {
sharedResource.produce(i);
System.out.println("Produced: " + i);
}
});
Thread consumer = new Thread(() -> {
for (int i = 0; i < 5; i++) {
int value = sharedResource.consume();
System.out.println("Consumed: " + value);
}
});
producer.start();
consumer.start();
}
}
join()
方法使一个线程等待另一个线程执行完毕。通常用于确保某个线程在另一个线程结束后才开始执行。
示例代码:
public class JoinDemo {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 1 - " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(() -> {
try {
t1.join(); // 等待 t1 线程执行完毕
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 5; i++) {
System.out.println("Thread 2 - " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
}
}
Thread.sleep()
方法使当前线程休眠指定的时间。虽然 sleep()
本身不用于线程间通信,但可以在多线程环境中使用它来控制线程执行的节奏。
示例代码:
public class SleepDemo {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Thread 1 - " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
}
}
Lock
和 Condition
接口更灵活和强大的线程同步和通信机制,特别是与 ReentrantLock
一起使用。
示例代码:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class SharedResourceWithLock {
private int value;
private boolean available = false;
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
public void produce(int newValue) {
lock.lock();
try {
while (available) {
condition.await();
}
value = newValue;
available = true;
condition.signal();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
public int consume() {
lock.lock();
try {
while (!available) {
condition.await();
}
available = false;
condition.signal();
return value;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return -1;
} finally {
lock.unlock();
}
}
}
public class LockConditionDemo {
public static void main(String[] args) {
SharedResourceWithLock sharedResource = new SharedResourceWithLock();
Thread producer = new Thread(() -> {
for (int i = 0; i < 5; i++) {
sharedResource.produce(i);
System.out.println("Produced: " + i);
}
});
Thread consumer = new Thread(() -> {
for (int i = 0; i < 5; i++) {
int value = sharedResource.consume();
System.out.println("Consumed: " + value);
}
});
producer.start();
consumer.start();
}
}
BlockingQueue
接口提供线程安全的阻塞队列实现,例如 ArrayBlockingQueue
和 LinkedBlockingQueue
,适用于生产者-消费者模型。
示例代码:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class BlockingQueueDemo {
public static void main(String[] args) {
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
Thread producer = new Thread(() -> {
try {
for (int i = 0; i < 5; i++) {
queue.put(i);
System.out.println("Produced: " + i);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread consumer = new Thread(() -> {
try {
for (int i = 0; i < 5; i++) {
int value = queue.take();
System.out.println("Consumed: " + value);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
producer.start();
consumer.start();
}
}
这些是 Java 中常用的线程间通信方式,每种方式都有其适用的场景和优缺点。根据实际需求选择合适的通信方式,可以有效地实现多线程编程中的数据共享和协调工作。
因篇幅问题不能全部显示,请点此查看更多更全内容