网站首页 > 精选教程 正文
在Java中,我们可以有很多的方式来实现两个或者是多个线程之间的数据共享操作,下面我们就来看看在Java中如何实现多个线程之间的数据共享操作,并且给出详细的实现方式。
使用共享对象
实现数据共享最简单的方式就是建立可以在多个线程之间共享数据的共享对象,共享对象可以是一个普通的Java对象,例如,List、Map、自定义的对象等。线程可以通过同步的方式访问和修改这个对象。如下所示。
class SharedData {
private int data;
public synchronized void setData(int data) {
this.data = data;
}
public synchronized int getData() {
return data;
}
}
public class SharedObjectExample {
public static void main(String[] args) {
SharedData sharedData = new SharedData();
Thread thread1 = new Thread(() -> {
sharedData.setData(100);
System.out.println("Thread 1 set data to 100");
});
Thread thread2 = new Thread(() -> {
System.out.println("Thread 2 read data: " + sharedData.getData());
});
thread1.start();
thread2.start();
}
}
使用volatile关键字
如果多个线程之间的数据传递只是一个简单的变量,例如int、boolean等,这个时候我们可以通过volatile关键字来确保变量的可见性,这样也可以实现在多个线程之间的数据共享操作,如下所示。
class SharedData {
private volatile int data;
public void setData(int data) {
this.data = data;
}
public int getData() {
return data;
}
}
public class VolatileExample {
public static void main(String[] args) {
SharedData sharedData = new SharedData();
Thread thread1 = new Thread(() -> {
sharedData.setData(100);
System.out.println("Thread 1 set data to 100");
});
Thread thread2 = new Thread(() -> {
System.out.println("Thread 2 read data: " + sharedData.getData());
});
thread1.start();
thread2.start();
}
}
使用java.util.concurrent包中的并发容器
当然除了上面的基础操作之外,我们还可以使用Java中提供的线程安全的容器类,如ConcurrentHashMap、CopyOnWriteArrayList等,这些线程安全类都可以实现在线程之间共享数据操作,如下所示。
import java.util.concurrent.ConcurrentHashMap;
public class ConcurrentMapExample {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> sharedMap = new ConcurrentHashMap<>();
Thread thread1 = new Thread(() -> {
sharedMap.put("key", 100);
System.out.println("Thread 1 put value 100 for key");
});
Thread thread2 = new Thread(() -> {
System.out.println("Thread 2 read value: " + sharedMap.get("key"));
});
thread1.start();
thread2.start();
}
}
使用wait() 和 notify() 方法
除了上面的基础方式和扩展并发类之外,在Java底层实现中,我们还可以通过使用Object类中的wait()和notify()方法可以实现线程之间的通信,从而实现数据共享,具体操作代码如下所示。
class SharedData {
private int data;
private boolean dataAvailable = false;
public synchronized void setData(int data) {
while (dataAvailable) {
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
this.data = data;
dataAvailable = true;
notifyAll();
}
public synchronized int getData() {
while (!dataAvailable) {
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
dataAvailable = false;
notifyAll();
return data;
}
}
public class WaitNotifyExample {
public static void main(String[] args) {
SharedData sharedData = new SharedData();
Thread producer = new Thread(() -> {
sharedData.setData(100);
System.out.println("Producer set data to 100");
});
Thread consumer = new Thread(() -> {
System.out.println("Consumer read data: " + sharedData.getData());
});
producer.start();
consumer.start();
}
}
使用Exchanger类
Exchanger类是Java中专门提供的一种在线程之间实现数据交换的操作机制,我们可以通过Exchanger类来实现线程之间的数据交换操作,如下所示。
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 = "Message from Thread 1";
System.out.println("Thread 1 is sending: " + message);
String reply = exchanger.exchange(message);
System.out.println("Thread 1 received: " + reply);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread thread2 = new Thread(() -> {
try {
String message = "Message from Thread 2";
System.out.println("Thread 2 is sending: " + message);
String reply = exchanger.exchange(message);
System.out.println("Thread 2 received: " + reply);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
thread1.start();
thread2.start();
}
}
总结
上面的方法,都可以实现线程之间的数据共享操作,我们可以根据在实际使用场景中的使用内容来选择合适的方式来实现线程之间的数据共享操作,对于比较简单的数据共享操作来讲,我们就选择简单容易实现的方式来实现数据共享,但是对于一些高并发场景中的数据共享来说,我们可以通过Java默认的并发容器以及后续扩展的交换器来实现数据的交换操作。
猜你喜欢
- 2024-12-23 应用Stream API与并行流处理大数据量集合操作
- 2024-12-23 字节二面:为什么SpringBoot的 jar可以直接运行?
- 2024-12-23 阿里云 SAE Web:百毫秒高弹性的实时事件中心的架构和挑战
- 2024-12-23 深入 Spring 框架:从核心到高级特性
- 2024-12-23 重学java:数据集合
- 2024-12-23 工业大数据平台技术架构方案(ppt)
- 2024-12-23 大数据整体架构技术方案(ppt)
- 2024-12-23 如何用20%技术解决80%问题?这份Java进阶架构师手册,告诉你答案
- 2024-12-23 深入探索 Java 复杂泛型:使用与限制全解析
- 2024-12-23 大学大数据平台架构规划方案(ppt)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)