java多线程之间怎么通信 - 面试宝典
【摘要】 在Java中,多线程之间可以通过以下几种方式进行通信:共享变量:多个线程可以共享同一个变量,并通过读写该变量来进行通信。需要注意的是,由于多个线程同时访问共享变量可能会导致竞态条件(Race Condition)等线程安全问题,因此需要对共享变量进行适当的同步操作,例如使用synchronized关键字或Lock对象进行加锁。 示例代码:javaCopy codepublic class S...
在Java中,多线程之间可以通过以下几种方式进行通信:
- 共享变量:多个线程可以共享同一个变量,并通过读写该变量来进行通信。需要注意的是,由于多个线程同时访问共享变量可能会导致竞态条件(Race Condition)等线程安全问题,因此需要对共享变量进行适当的同步操作,例如使用synchronized关键字或Lock对象进行加锁。 示例代码:
javaCopy codepublic class SharedVariableCommunication {
private static int sharedVariable = 0;
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
synchronized (SharedVariableCommunication.class) {
// 读取共享变量的值
int value = sharedVariable;
// 修改共享变量的值
sharedVariable = value + 1;
}
});
Thread thread2 = new Thread(() -> {
synchronized (SharedVariableCommunication.class) {
// 读取共享变量的值
int value = sharedVariable;
// 修改共享变量的值
sharedVariable = value + 1;
}
});
thread1.start();
thread2.start();
}
}
- 等待/通知机制:使用wait()、notify()和notifyAll()方法来实现线程之间的等待和通知。其中,wait()方法使当前线程进入等待状态,直到被其他线程调用notify()或notifyAll()方法来唤醒;notify()方法唤醒在该对象上等待的一个线程;notifyAll()方法唤醒在该对象上等待的所有线程。 示例代码:
javaCopy codepublic class WaitNotifyCommunication {
private static final Object lock = new Object();
private static boolean flag = false;
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
synchronized (lock) {
while (!flag) {
try {
// 线程进入等待状态
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 执行线程1的逻辑
}
});
Thread thread2 = new Thread(() -> {
synchronized (lock) {
// 执行线程2的逻辑
flag = true;
// 唤醒等待在该对象上的所有线程
lock.notifyAll();
}
});
thread1.start();
thread2.start();
}
}
- 使用阻塞队列:通过阻塞队列(例如ArrayBlockingQueue、LinkedBlockingQueue等)来实现线程之间的数据传递。阻塞队列提供了put()和take()方法,分别用于向队列中添加元素和从队列中获取元素,如果队列为空或已满,则阻塞线程,直到条件满足。 示例代码:
javaCopy codeimport java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class BlockingQueueCommunication {
private static BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(1);
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
try {
// 从队列中获取元素
int value = queue.take();
// 执行线程1的逻辑
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread thread2 = new Thread(() -> {
try {
// 向队列中添加元素
queue.put(1);
// 执行线程2的逻辑
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread1.start();
thread2.start();
}
}
4. Condition条件变量:Condition是在Java 5中引入的用于替代传统的Object的wait()和notify()方法的方式,它提供了更加灵活和精细的线程通信机制。通过Lock对象的newCondition()方法创建一个Condition对象,并使用await()和signal()方法来实现线程等待和唤醒操作。 示例代码:
javaCopy codeimport java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionCommunication {
private static Lock lock = new ReentrantLock();
private static Condition condition = lock.newCondition();
private static boolean flag = false;
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
lock.lock();
try {
while (!flag) {
try {
// 线程进入等待状态
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 执行线程1的逻辑
} finally {
lock.unlock();
}
});
Thread thread2 = new Thread(() -> {
lock.lock();
try {
// 执行线程2的逻辑
flag = true;
// 唤醒等待的线程
condition.signal();
} finally {
lock.unlock();
}
});
thread1.start();
thread2.start();
}
}
- CountDownLatch:CountDownLatch是一个同步工具类,它可以让一个或多个线程等待其他线程完成操作后再继续执行。在CountDownLatch对象创建时需要指定一个计数值,当计数值为0时,等待的线程就可以继续执行。 示例代码:
javaCopy codeimport java.util.concurrent.CountDownLatch;
public class CountDownLatchCommunication {
private static CountDownLatch latch = new CountDownLatch(1);
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
try {
// 等待CountDownLatch计数值为0
latch.await();
// 执行线程1的逻辑
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread thread2 = new Thread(() -> {
// 执行线程2的逻辑
latch.countDown(); // 将CountDownLatch计数值减1
});
thread1.start();
thread2.start();
}
}
这些方式都可以实现多线程之间的通信,选择合适的方式取决于具体的需求和场景。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
皮牙子抓饭2023/08/10 13:35:251楼编辑删除举报