线程--简单多线程通信实例

来源:互联网 发布:淘宝微商怎么做 编辑:程序博客网 时间:2024/05/22 07:51

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基础入门 传智博客高教产品研发部 

本人郑重声明,本博客所著文章、图片版权归权利人持有,本博只做学习交流分享所用,不做任何商业用途。访问者可將本博提供的內容或服务用于个人学习、研究或欣赏,不得用于商业使用。同時,访问者应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人的合法权利;如果用于商业用途,须征得相关权利人的书面授权。若以上文章、图片的原作者不愿意在此展示內容,请及时通知在下,將及时予以刪除。