教育路上
摘要:java多线程通信,这两个线程之间需要协同完成工作,就需要线程之间进行通信。Java 多线程通信。以下是我们为大家整理的,相信大家阅读完后肯定有了自己的选择吧。
2022-05-19 14:07网络推荐
现代社会崇尚合作精神,分工合作在日常生活和工作中无处不在。举个简单的例子,比如
一条生产线的上下两个工序,它们必须以规定的速率完成各自的工作,才能保证产品在流水
线中顺利的流转。如果下工序过慢,会造成产品在两道工序之间的积压;如果上工序过慢,
会造成下工序长时间无事可做。在多线程的程序中,上下工序可以看作两个线程,这两个线
程之间需要协同完成工作,就需要线程之间进行通信。
14.6.1 问题引入
为了更好地理解线程间的通信,我们可以模拟这样的一种应用场景,假设有两个线程
同时去操作同一个存储空间,其中一个线程负责向存储空间中存入数据,另一个线程负责取
出数据。通过一个案例来实现上述情况,首先定义一个类,在类中使用一个数组来表示存储
空间,并提供数据的存取方法具体实现如例 14-15 所示
例 14-15 Storage.java
class Storage {
// 数据存储数组
private int[] cells = new int[10];
// inPos 表示存入时数组下标,outPos 表示取出时数组下标
private int inPos, outPos;
// 定义一个 put()方法向数组中存入数据
public void put(int num) {
cells[inPos] = num;
System.out.println("在 cells[" + inPos + "]中放入数据---" + cells[inPos]);
inPos++;// 存完元素让位置加 1
if (inPos == cells.length)
inPos = 0; // 当 inPos 为数组长度时,将其置为 0
}
// 定义一个 get()方法从数组中取出数据
public void get() {
int data = cells[outPos];
System.out.println("从 celss[" + outPos + "]中取出数据" + data);
outPos++; // 取完元素让位置加 1
if (outPos == cells.length)
outPos = 0;
}
}
例 14-15 中,定义的数组 cells 用来存储数据,put( )方法用于向数组存入数据,get()方法
用于获取数据。针对数组元素的存取操作都是从第一个元素开始依次执行的,每当操作完数
组的最后一个元素时,索引都会被置为 0,也就是重新从数组的第一个位置开始存取操作
接下来实现两个线程同时访问上例中的共享数据,这两个线程都需要实现Runable接口,
具体如例 14-16 所示。
例 14-16 Input.java 和 Output.java
class Input implements Runnable{ // 输入线程类
private Storage st ;
private int num; // 定义一个变量 num
Input(Storage st){ // 通过构造方法接收一个 Storage 对
象
this.st = st;
}
public void run(){
while(true){
st.put(num++); // 将 num 存入数组,每次存入后 num
自增
}
}
}
class Output implements Runnable{ //输出线程类
private Storage st ;
Output(Storage st){
this.st = st;
}
public void run(){
while(true){
st.get();
}
}
}
例 14-16 中,定义了两个类 lnput 和 Ouput,它们都实现了 Runnable 接口,并且构造方
法中都接收一个 Storage 类型的对象。在 Input 类的 run()方法中使用 while 循环不停地向存
储空间中存人数据 num,并在每次存入数据后将 num 进行自增,从而实现存入自然数 1、2、
3、4…的效果。在 Output 类的 run( )方法中使用 while 循环不停地从存储空间中取出数据。
最后需要写一个测试程序,开启两个线程分别运行 Input 和 Output 类中的代码,如例 14-17
所示。
例 14-17 Example15.java
public class Example15 {
public static void main(String[] args) {
Storage st = new Storage(); // 创建数据存储类对象
Input input = new Input(st); // 创建 Input 对象传入 Storage 对象
Output output = new Output(st); // 创建 Output 对象传入 Storage 对象
new Thread(input).start(); // 开启新线程
new Thread(output).start(); // 开启新线程
}
}
运行结果如图 14-19 所示
从图 14-19 运行结果可以看到,Input 线程依次向数组中存入递增的自然数 1、2、3、
4…,而 Output 线程依次取出数组中的数据。其中特殊标记的两行运行结果表示在取出数字
12 后,紧接着取出的是 23,这样的现象明显是不对的。我们希望出现的运行结果是依次取出
递增的自然数。之所以出现这种现象是因为在 Input 线程存入数字 13 时,Output 线程并没
有及时取出数据,Input 线程一直在持续地存入数据,直到将数组放满,又从数组的第一位置
开始存人 21、22、23…Output 线程再次取出数据时,取出的不再是 13 而是 23。
访客的评论 2024/03/29 19:32
文中描述的是准确的吗,如何报名!