Java线程(三):线程协作-生产者/消费者模式
来源:互联网 发布:python def返回多个 编辑:程序博客网 时间:2024/06/18 04:39
上一篇:Java线程(二)
上一篇讲述了线程的互斥(同步),但是在很多情况下,仅仅同步是不够的,还需要线程与线程协作(通信),生产者/消费者模式是一个经典的线程同步以及通信的模型。
假设有这样一种情况,有一个盘子,盘子里只能放一个鸡蛋,A线程专门往盘子里放鸡蛋,如果盘子里有鸡蛋,则一直等到盘子里没鸡蛋,B线程专门从盘子里取鸡蛋,如果盘子里没鸡蛋,则一直等到盘子里有鸡蛋。这里盘子是一个互斥区,每次放鸡蛋是互斥的,每次取鸡蛋也是互斥的,A线程放鸡蛋,如果这时B线程要取鸡蛋,由于A没有释放锁,B线程处于等待状态,进入阻塞队列,放鸡蛋之后,要通知B线程取鸡蛋,B线程进入就绪队列,反过来,B线程取鸡蛋,如果A线程要放鸡蛋,由于B线程没有释放锁,A线程处于等待状态,进入阻塞队列,取鸡蛋之后,要通知A线程放鸡蛋,A线程进入就绪队列。我们希望当盘子里有鸡蛋时,A线程阻塞,B线程就绪,盘子里没鸡蛋时,A线程就绪,B线程阻塞,代码如下:
- import java.util.ArrayList;
- import java.util.List;
- /** 定义一个盘子类,可以放鸡蛋和取鸡蛋 */
- public class Plate {
- /** 装鸡蛋的盘子 */
- List<Object> eggs = new ArrayList<Object>();
- /** 取鸡蛋 */
- public synchronized Object getEgg() {
- while (eggs.size() == 0) {
- try {
- wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- Object egg = eggs.get(0);
- eggs.clear();// 清空盘子
- notify();// 唤醒阻塞队列的某线程到就绪队列
- System.out.println("拿到鸡蛋");
- return egg;
- }
- /** 放鸡蛋 */
- public synchronized void putEgg(Object egg) {
- while (eggs.size() > 0) {
- try {
- wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- eggs.add(egg);// 往盘子里放鸡蛋
- notify();// 唤醒阻塞队列的某线程到就绪队列
- System.out.println("放入鸡蛋");
- }
- static class AddThread extends Thread {
- private Plate plate;
- private Object egg = new Object();
- public AddThread(Plate plate) {
- this.plate = plate;
- }
- public void run() {
- plate.putEgg(egg);
- }
- }
- static class GetThread extends Thread {
- private Plate plate;
- public GetThread(Plate plate) {
- this.plate = plate;
- }
- public void run() {
- plate.getEgg();
- }
- }
- public static void main(String args[]) {
- Plate plate = new Plate();
- for(int i = 0; i < 10; i++) {
- new Thread(new AddThread(plate)).start();
- new Thread(new GetThread(plate)).start();
- }
- }
- }
- 放入鸡蛋
- 拿到鸡蛋
- 放入鸡蛋
- 拿到鸡蛋
- 放入鸡蛋
- 拿到鸡蛋
- 放入鸡蛋
- 拿到鸡蛋
- 放入鸡蛋
- 拿到鸡蛋
- 放入鸡蛋
- 拿到鸡蛋
- 放入鸡蛋
- 拿到鸡蛋
- 放入鸡蛋
- 拿到鸡蛋
- 放入鸡蛋
- 拿到鸡蛋
- 放入鸡蛋
- 拿到鸡蛋
前段时间看了张孝祥老师线程的视频,讲述了一个其学员的面试题,也是线程通信的,在此也分享一下。
题目:子线程循环10次,主线程循环100次,如此循环100次,好像是空中网的笔试题。
- public class ThreadTest2 {
- public static void main(String[] args) {
- final Business business = new Business();
- new Thread(new Runnable() {
- @Override
- public void run() {
- threadExecute(business, "sub");
- }
- }).start();
- threadExecute(business, "main");
- }
- public static void threadExecute(Business business, String threadType) {
- for(int i = 0; i < 100; i++) {
- try {
- if("main".equals(threadType)) {
- business.main(i);
- } else {
- business.sub(i);
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- class Business {
- private boolean bool = true;
- public synchronized void main(int loop) throws InterruptedException {
- while(bool) {
- this.wait();
- }
- for(int i = 0; i < 100; i++) {
- System.out.println("main thread seq of " + i + ", loop of " + loop);
- }
- bool = true;
- this.notify();
- }
- public synchronized void sub(int loop) throws InterruptedException {
- while(!bool) {
- this.wait();
- }
- for(int i = 0; i < 10; i++) {
- System.out.println("sub thread seq of " + i + ", loop of " + loop);
- }
- bool = false;
- this.notify();
- }
- }
下一篇:Java线程(四)
本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7433673。- Java线程(三):线程协作-生产者/消费者模式
- Java线程(三):线程协作-生产者/消费者模式
- Java线程(三):线程协作-生产者/消费者模式
- Java线程(三):线程协作-生产者/消费者模式
- 线程协作-生产者/消费者模式
- Java线程(三):线程协作-生产者/消费者问题
- Java线程(三):线程协作-生产者/消费者问题
- Java线程(三):线程协作-生产者/消费者问题
- Java线程(三):线程协作-生产者/消费者问题
- Java线程(三):线程协作-生产者/消费者问题
- Java线程(三):线程协作-生产者/消费者问题
- Java线程(三):线程协作-生产者/消费者问题
- Java线程(三):线程协作-生产者/消费者问题
- Java线程(三):线程协作-生产者/消费者问题
- Java线程(三):线程协作-生产者/消费者问题
- Java线程(三):线程协作-生产者/消费者问题
- Java线程(三):线程协作-生产者/消费者问题
- Java线程(三):线程协作-生产者/消费者问题
- 一台服务器如何同时运行多个tomcat
- MyBatis映射文件的resultMap如何做表关联
- objective-c kvo
- Android Fragment完全解析,关于碎片你所需知道的一切
- js 输入框只能输入数字
- Java线程(三):线程协作-生产者/消费者模式
- BT币(金融有风险,投资需谨慎)哥的失败投资
- Eclipse开启错误“Failed to create the java virtual machine.”的解决方法
- Android Fragment完全解析,关于碎片你所需知道的一切
- Android 电源管理——gotosleep和userActivity关注
- JavaWeb -- 四个域对比 request,servletContext, Session, pageContext
- hdu1175连连看(BFS)
- Java线程(四):Timer和TimerTask
- cloudera manage出现host是bad health