在 Java 中,线程之间的通信是实现多线程协作的重要手段。线程通信的主要目的是让多个线程能够协调工作,共享数据或通知彼此状态的变化。Java 提供了多种机制来实现线程之间的通信,主要包括以下几种方式:
1. 共享变量
线程可以通过共享变量进行通信,但需要确保对共享变量的访问是线程安全的。常用的方法包括:
volatile
关键字:确保变量的可见性。synchronized
关键字:确保对共享变量的访问是原子的。- 原子类:如
AtomicInteger
、AtomicLong
等,提供原子操作。
示例:
public class SharedVariableExample {
private volatile boolean flag = false;
public void setFlag() {
flag = true;
}
public void waitForFlag() {
while (!flag) {
// 等待 flag 变为 true
}
System.out.println("Flag is true!");
}
public static void main(String[] args) {
SharedVariableExample example = new SharedVariableExample();
Thread thread1 = new Thread(example::waitForFlag);
Thread thread2 = new Thread(example::setFlag);
thread1.start();
thread2.start();
}
}
2. wait()
和 notify()
/ notifyAll()
wait()
、notify()
和 notifyAll()
是 Object
类的方法,用于实现线程之间的等待和通知机制。这些方法必须在 synchronized
代码块或方法中使用。
wait()
:使当前线程进入等待状态,并释放锁。notify()
:唤醒一个等待的线程。notifyAll()
:唤醒所有等待的线程。
示例:
public class WaitNotifyExample {
private final Object lock = new Object();
private boolean isReady = false;
public void waitForReady() throws InterruptedException {
synchronized (lock) {
while (!isReady) {
lock.wait(); // 等待通知
}
System.out.println("Ready!");
}
}
public void setReady() {
synchronized (lock) {
isReady = true;
lock.notifyAll(); // 通知所有等待的线程
}
}
public static void main(String[] args) {
WaitNotifyExample example = new WaitNotifyExample();
Thread thread1 = new Thread(() -> {
try {
example.waitForReady();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread thread2 = new Thread(example::setReady);
thread1.start();
thread2.start();
}
}
3. BlockingQueue
BlockingQueue
是 java.util.concurrent
包中的一个接口,提供了线程安全的队列操作。它支持阻塞的插入和移除操作,常用于生产者-消费者模型。
示例:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class BlockingQueueExample {
public static void main(String[] args) {
BlockingQueue<String> queue = new LinkedBlockingQueue<>();
// 生产者线程
Thread producer = new Thread(() -> {
try {
queue.put("Message");
System.out.println("Produced: Message");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// 消费者线程
Thread consumer = new Thread(() -> {
try {
String message = queue.take();
System.out.println("Consumed: " + message);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
producer.start();
consumer.start();
}
}
4. CountDownLatch
CountDownLatch
是 java.util.concurrent
包中的一个同步工具,用于让一个或多个线程等待其他线程完成操作。
示例:
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(2);
Thread thread1 = new Thread(() -> {
System.out.println("Thread 1 is running");
latch.countDown();
});
Thread thread2 = new Thread(() -> {
System.out.println("Thread 2 is running");
latch.countDown();
});
thread1.start();
thread2.start();
latch.await(); // 等待两个线程完成
System.out.println("All threads have finished!");
}
}
5. CyclicBarrier
CyclicBarrier
是 java.util.concurrent
包中的一个同步工具,用于让一组线程互相等待,直到所有线程都到达某个屏障点。
示例:
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(2, () -> {
System.out.println("All threads have reached the barrier!");
});
Thread thread1 = new Thread(() -> {
try {
System.out.println("Thread 1 is running");
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
});
Thread thread2 = new Thread(() -> {
try {
System.out.println("Thread 2 is running");
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
});
thread1.start();
thread2.start();
}
}
6. Exchanger
Exchanger
是 java.util.concurrent
包中的一个同步工具,用于在两个线程之间交换数据。
示例:
import java.util.concurrent.Exchanger;
public class ExchangerExample {
public static void main(String[] args) {
Exchanger<String> exchanger = new Exchanger<>();
Thread thread1 = new Thread(() -> {
try {
String message = exchanger.exchange("Message from Thread 1");
System.out.println("Thread 1 received: " + message);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread thread2 = new Thread(() -> {
try {
String message = exchanger.exchange("Message from Thread 2");
System.out.println("Thread 2 received: " + message);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread1.start();
thread2.start();
}
}
总结
Java 提供了多种线程通信机制,包括共享变量、wait()
/notify()
、BlockingQueue
、CountDownLatch
、CyclicBarrier
和 Exchanger
等。选择合适的机制取决于具体的应用场景和需求。
THE END
暂无评论内容