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

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

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

	}
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值