Java线程间的通信方式详解
在Java中,线程间的通信是指两个或多个线程之间通过某种方式进行交流、协作的过程,Java线程间的通信主要有以下几种方式:
1.共享内存
共享内存是指多个线程之间共享同一块内存区域,通过修改该内存区域来实现线程之间的通信。Java中的共享内存通信方式有synchronized
、volatile
、wait
和notify
等。
示例1:使用synchronized
实现线程同步
public class ShareMemoryDemo {
private static boolean flag = false;
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
while (true) {
synchronized (ShareMemoryDemo.class) {
if (flag) {
System.out.println("线程1");
flag = false;
ShareMemoryDemo.class.notify();
} else {
try {
ShareMemoryDemo.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
Thread t2 = new Thread(() -> {
while (true) {
synchronized (ShareMemoryDemo.class) {
if (!flag) {
System.out.println("线程2");
flag = true;
ShareMemoryDemo.class.notify();
} else {
try {
ShareMemoryDemo.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
t1.start();
t2.start();
}
}
在上述示例中,flag
变量被用作一个标记,用来表示两个线程之间的通信状态。线程1和线程2交替打印输出。
示例2:使用wait
和notify
实现生产者-消费者模型
import java.util.LinkedList;
public class ProducerConsumerDemo {
private LinkedList<Integer> storage = new LinkedList<>();
private final int MAX_SIZE = 10;
public void produce() {
while (true) {
synchronized (storage) {
while (storage.size() >= MAX_SIZE) {
try {
System.out.println("仓库已满,生产者等待...");
storage.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int num = (int) (Math.random() * 100);
storage.add(num);
System.out.println("生产了一个产品: " + num);
storage.notify();
}
}
}
public void consume() {
while (true) {
synchronized (storage) {
while (storage.isEmpty()) {
try {
System.out.println("仓库已空,消费者等待...");
storage.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int num = storage.removeFirst();
System.out.println("消费了一个产品:" + num);
storage.notify();
}
}
}
public static void main(String[] args) {
ProducerConsumerDemo demo = new ProducerConsumerDemo();
Thread producer = new Thread(() -> {
demo.produce();
});
Thread consumer = new Thread(() -> {
demo.consume();
});
producer.start();
consumer.start();
}
}
在上述示例中,使用LinkedList
作为共享变量,生产者每次随机生成一个数字并存入LinkedList
中,消费者每次从LinkedList
中取出第一个数字并消费。如果LinkedList
已满,则生产者线程等待,如果LinkedList
为空,则消费者线程等待。
2. 消息传递
消息传递是指线程间通过发送消息的方式实现通信。Java中的消息传递通信方式主要有BlockingQueue
和Semaphore
等。
示例1:使用BlockingQueue
实现生产者-消费者模型
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(() -> {
while (true) {
try {
int num = (int) (Math.random() * 100);
queue.put(num);
System.out.println("生产了一个产品: " + num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread consumer = new Thread(() -> {
while (true) {
try {
int num = queue.take();
System.out.println("消费了一个产品:" + num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
producer.start();
consumer.start();
}
}
在上述示例中,使用BlockingQueue
作为消息传递方式进行线程间通信。生产者线程每次随机生成一个数字并存入BlockingQueue
中,消费者线程每次从BlockingQueue
中取出一个数字并消费,如果BlockingQueue
已满,则生产者线程阻塞,如果BlockingQueue
为空,则消费者线程阻塞。
示例2:使用Semaphore
实现多线程限流
import java.util.concurrent.Semaphore;
public class SemaphoreDemo {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(5);
for (int i = 1; i <= 10; i++) {
Thread t = new Thread(() -> {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + "进入,当前还有" + semaphore.availablePermits() + "个许可");
Thread.sleep(1000);
semaphore.release();
System.out.println(Thread.currentThread().getName() + "离开,当前还有" + semaphore.availablePermits() + "个许可");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "线程" + i);
t.start();
}
}
}
在上述示例中,使用Semaphore
作为消息传递方式进行线程间通信,通过调用semaphore.acquire()
获取一个许可,如果所有许可都已经被获取,则线程阻塞。线程执行完任务后,调用semaphore.release()
释放许可。
3. 远程调用
远程调用是指通过网络传输调用远程计算机中的方法,实现跨计算机之间的通信。Java中的远程调用通信方式有RMI
、Hessian
、Http
等。
对于远程调用的使用,这里不做详细的展开。
4. 信号量
信号量是指通过锁可以获取的许可数量控制同时访问某个资源的线程数量,实现对资源的并发访问控制。Java中的信号量通信方式有Semaphore
、CountDownLatch
和CyclicBarrier
等。
对于信号量的使用,这里已经在上述示例中有展开,不再重复。
总结
以上是Java线程间的通信方式的详细讲解和示例,不同的通信方式适合不同的场景,具体要根据项目需求和性能情况进行选择和应用。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java线程间的通信方式详解 - Python技术站