您的位置:首页 > 编程语言 > Java开发

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

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

线程间的通信必须要有: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;
}

@Override
public 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的wait
ms[index] = mt;// 装入馒头
index++; // 计数馒头的个数
System.out.println("装第" + index + "个馒头");
}

// 出栈,相当于消费馒头
public synchronized Mt pop() throws Exception {
// 取出馒头,index等于0的时候,说明馒头取完了,停止取馒头
if (index == 0) {
// 让线程进入等待,以停止取出馒头
wait();// pop等待
}
notify();// 唤醒push的wait
System.out.println("取出第" + index + "个馒头");
index--; // 每取出一个减一个
return ms[index]; // 返回取出的馒头
}
}

创建一个生产者,用于生产馒头。
/**
* 生产者
*
* @author Administrator
*
*/
public class Producter implement
4000
s 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();

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: