1、多线程通信
两个线程同时操作一个存储空间,一个存数据,一读数据。并且按照一定的顺序轮流执行。Object提供wait(),notify(),notify All(),方法用于解决线程间通信问题。
1.1、代码
package com.example;
public class MyThreadCommit {
public static void main (String [] args){
Storage st = new Storage();//创建数据存储类对象
Input input = new Input(st);//创建Input 对象传入Storage对象
Output output = new Output(st);//创建传入Storage对象
new Thread(input).start();
new Thread(output).start();
}
}
class Input implements Runnable{ //输入线程
private Storage st;
private int num; //定义一个变量
Input(Storage st){ //通过构造方法来接受一个Storage对象
this.st=st;
}
public void run(){
while (true){
st.put(num++); //将num存入数组,每次存入后 +1
}
}
}
class Output implements Runnable{//输出线程类
private Storage st;
Output(Storage st){
this.st=st; //构造方法接受一个Storage 对象
}
public void run(){
while(true){
st.get(); //循环取出元素
}
}
}
class Storage {
private int [] cells = new int[10]; //数据存储数组
private int inPos,outPos;//inPos 存入时的数组下标,outPos取出时的数组下标
private int count; //存入或取出时数据的数量
public synchronized void put(int num){
try {
while (count == cells.length){
this.wait();
}
cells[inPos]=num;//向数组中放入数据
System.out.println("在cells["+inPos+"]中放入数据---"+cells[inPos]);
inPos++; //存完元素让位置加1
if (inPos == cells.length){
inPos = 0; //当cells[9]放完数据后再从cells[0]开始
}
count ++; //每方一个数据count 加1
this.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void get(){
try {
while (count == 0) { //如果count为0,此线程等待
this.wait();
}
int data = cells[outPos];//从数组中取出数据
System.out.println("在cells["+outPos+"]中取出数据---"+data);
cells[outPos]=0;//当取出数据时,当前数据值为0
outPos++;//取万后位置+1
if(outPos == cells.length){
outPos=0;//当从cells[9]中取完数据后再从cells[0]开始
}
count--;//每取一个元素count -1
this.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
1.2、运行结果
在cells[2]中放入数据---3759862
在cells[3]中放入数据---3759863
在cells[4]中放入数据---3759864
在cells[5]中放入数据---3759865
在cells[6]中放入数据---3759866
在cells[7]中放入数据---3759867
在cells[8]中放入数据---3759868
在cells[9]中放入数据---3759869
在cells[0]中放入数据---3759870
在cells[1]中取出数据---3759861
在cells[2]中取出数据---3759862
在cells[3]中取出数据---3759863
在cells[4]中取出数据---3759864
在cells[5]中取出数据---3759865
在cells[6]中取出数据---3759866
在cells[7]中取出数据---3759867
在cells[8]中取出数据---3759868
在cells[9]中取出数据---3759869
在cells[0]中取出数据---3759870
在cells[1]中放入数据---3759871
在cells[2]中放入数据---3759872
在cells[3]中放入数据---3759873
在cells[4]中放入数据---3759874
首先使用synchorized关键字将put()方法和get()方法修饰为同步方法,之后每操作一次数据,便调用一次notify()方法唤醒 对应同步锁上等待的线程。
当存入数据时,如果count的值和cells数组的长度相等,说明数组已经填满,此时调用同步锁的wait()方法使存入数据的线程进入等待状态。
当取出数据时,如果count的值为0,说明数组已经被取空,此时就需要调用同步锁的wait()方法,使取出数据的线程进入等待状态。
参考文档:
Java基础入门 传智博客高教产品研发部
本人郑重声明,本博客所著文章、图片版权归权利人持有,本博只做学习交流分享所用,不做任何商业用途。访问者可將本博提供的內容或服务用于个人学习、研究或欣赏,不得用于商业使用。同時,访问者应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人的合法权利;如果用于商业用途,须征得相关权利人的书面授权。若以上文章、图片的原作者不愿意在此展示內容,请及时通知在下,將及时予以刪除。