【Java编程】多线程之线程间的通信

来源:互联网 发布:电脑版ftp 软件 编辑:程序博客网 时间:2024/05/21 17:06

线程间的通信:线程间的通信就是线程之间的互相交流,有时一件事情不是一个线程可以完成的需要多个线程的相互合作才能完成某件事情。

线程间的通信必须要有:wait 等待和notify来完成,其中完成线程间的通信还需要给线程上锁。就是使用synchronized来给方法上锁。

例:

public synchronized void test() {}

下面给出一个线程间的通信所使用的经典例子。

生产者和消费者,生产者不断的生产,消费者不断的取走。

生产馒头。

首先我们来分析一下。

1.需要创建一个馒头类,产生馒头。

2.需要一个装馒头的容器

3.需要生产者,所以创建一个生产者。

4需要消费者,所以创建一个消费者。

5创建一个测试类来测试。

下面开始写代码:

创建一个馒头类,用于产生馒头。

/** * 馒头类 *  * @author Administrator * */public class Mt {int no; // 馒头的编号public Mt(int no) {this.no = no;}@Overridepublic String toString() {return "Mt [no=" + no + "]";}}


创建一个容器用于存放馒头,这里称为馒头框。

/** * 馒头框 *  * @author Administrator * */public class MtStack {int index = 0; // 做一个标记使用Mt[] ms = new Mt[6]; // 定义一个容器,可以装6个馒头// 压栈,就相当于生产馒头public synchronized void push(Mt mt) throws Exception {// 判断当馒头的个数等于筐的大小的时候说明装满了,停止生产馒头if (index == ms.length) {// 让线程进入等待,以停止生产馒头wait();// push等待}notify();// 唤醒pop的waitms[index] = mt;// 装入馒头index++; // 计数馒头的个数System.out.println("装第" + index + "个馒头");}// 出栈,相当于消费馒头public synchronized Mt pop() throws Exception {// 取出馒头,index等于0的时候,说明馒头取完了,停止取馒头if (index == 0) {// 让线程进入等待,以停止取出馒头wait();// pop等待}notify();// 唤醒push的waitSystem.out.println("取出第" + index + "个馒头");index--; // 每取出一个减一个return ms[index]; // 返回取出的馒头}}


创建一个生产者,用于生产馒头。

/** * 生产者 *  * @author Administrator * */public class Producter implements Runnable {MtStack mts; // 定义个馒头筐public Producter(MtStack mts) {this.mts = mts;}@Override// 生产馒头public synchronized void run() {// 获取当前线程的名称String name = Thread.currentThread().getName();System.out.println(name + ":开始生产馒头");// 生产20个馒头for (int i = 1; i <= 20; i++) {// new一个馒头Mt mt = new Mt(i);System.out.println(name + ":生产" + mt + "个馒头");try {mts.push(mt); // 姜馒头装入筐中Thread.sleep(10);// 睡眠10毫秒} catch (Exception e) {e.printStackTrace();}}}}

创建一个消费者

/** * 消费者 *  * @author Administrator * */public class Saler implements Runnable {MtStack mts;public Saler(MtStack mts) {this.mts = mts;}@Override// 消费馒头public void run() {System.out.println("开始消费馒头");for (int i = 1; i <= 20; i++) {try {Mt mt = mts.pop();System.out.println("取出馒头:"+mt);Thread.sleep(100);} catch (Exception e) {e.printStackTrace();}}}}

定义一个测试类

public class Test {public static void main(String[] args) {MtStack mts = new MtStack();// 馒头框Producter p1 = new Producter(mts);Saler s = new Saler(mts);Thread t1 = new Thread(p1);Thread t2 = new Thread(s);t1.start();t2.start();}}