线程协作-生产者/消费者问题

处理线程协作时,在同步方法中,必须作进入检查,如果不满足进入条件,须放弃锁,进入等待

完成业务处理后,要做清场处理,同时完成唤醒其他等待的线程的操作

1. import java.util.ArrayList;

2. import java.util.List;

3. /** 定义一个盘子类,可以放鸡蛋和取鸡蛋 */

4. public class Plate {

5.     /** 装鸡蛋的盘子 */

6.     List<Object> eggs = new ArrayList<Object>();

7.     /** 取鸡蛋 */

8.     public synchronized Object getEgg() {

9.         while (eggs.size() == 0) {

10.             try {

11.                 wait();

12.             } catch (InterruptedException e) {

13.                 e.printStackTrace();

14.             }

15.         }

16.         Object egg = eggs.get(0);

17.         eggs.clear();// 清空盘子

18.         notify();// 唤醒阻塞队列的某线程到就绪队列

19.         System.out.println("拿到鸡蛋");

20.         return egg;

21.     }

22.     /** 放鸡蛋 */

23.     public synchronized void putEgg(Object egg) {

24.         while (eggs.size() > 0) {

25.             try {

26.                 wait();

27.             } catch (InterruptedException e) {

28.                 e.printStackTrace();

29.             }

30.         }

31.         eggs.add(egg);// 往盘子里放鸡蛋

32.         notify();// 唤醒阻塞队列的某线程到就绪队列

33.         System.out.println("放入鸡蛋");

34.     }

35.     static class AddThread implements Runnable  {

36.         private Plate plate;

37.         private Object egg = new Object();

38.         public AddThread(Plate plate) {

39.             this.plate = plate;

40.         }

41.         public void run() {

42.             plate.putEgg(egg);

43.         }

44.     }

45.     static class GetThread implements Runnable  {

46.         private Plate plate;

47.         public GetThread(Plate plate) {

48.             this.plate = plate;

49.         }

50.         public void run() {

51.             plate.getEgg();

52.         }

53.     }

54.     public static void main(String args[]) {

55.         Plate plate = new Plate();

56.         for(int i = 0; i < 10; i++) {

57.             new Thread(new AddThread(plate)).start();

58.             new Thread(new GetThread(plate)).start();

59.         }

60.     }

61. }

1. import java.util.ArrayList;

2. import java.util.List;

3. /** 定义一个盘子类,可以放鸡蛋和取鸡蛋 */

4. public class Plate {

5.     /** 装鸡蛋的盘子 */

6.     List<Object> eggs = new ArrayList<Object>();

7.     /** 取鸡蛋 */

8.     public synchronized Object getEgg() {

9.         while (eggs.size() == 0) {

10.             try {

11.                 wait();

12.             } catch (InterruptedException e) {

13.                 e.printStackTrace();

14.             }

15.         }

16.         Object egg = eggs.get(0);

17.         eggs.clear();// 清空盘子

18.         notify();// 唤醒阻塞队列的某线程到就绪队列

19.         System.out.println("拿到鸡蛋");

20.         return egg;

21.     }

22.     /** 放鸡蛋 */

23.     public synchronized void putEgg(Object egg) {

24.         while (eggs.size() > 0) {

25.             try {

26.                 wait();

27.             } catch (InterruptedException e) {

28.                 e.printStackTrace();

29.             }

30.         }

31.         eggs.add(egg);// 往盘子里放鸡蛋

32.         notify();// 唤醒阻塞队列的某线程到就绪队列

33.         System.out.println("放入鸡蛋");

34.     }

35.     static class AddThread implements Runnable  {

36.         private Plate plate;

37.         private Object egg = new Object();

38.         public AddThread(Plate plate) {

39.             this.plate = plate;

40.         }

41.         public void run() {

42.             plate.putEgg(egg);

43.         }

44.     }

45.     static class GetThread implements Runnable  {

46.         private Plate plate;

47.         public GetThread(Plate plate) {

48.             this.plate = plate;

49.         }

50.         public void run() {

51.             plate.getEgg();

52.         }

53.     }

54.     public static void main(String args[]) {

55.         Plate plate = new Plate();

56.         for(int i = 0; i < 10; i++) {

57.             new Thread(new AddThread(plate)).start();

58.             new Thread(new GetThread(plate)).start();

59.         }

60.     }

61. }

时间: 2024-10-28 09:39:01

线程协作-生产者/消费者问题的相关文章

JAVA并发编程6_线程协作/生产者-消费者

前面通过同步锁来同步任务的行为,两个任务在交替访问共享资源的时候,可以通过使用同步锁使得任何时候只有一个任务可以访问该资源,见博客:线程同步之synchronized关键字.下面主要讲的是如何使任务彼此间可以协作,使得多个任务可以一起工作去解决木某个问题,因为有些问题中,某些部分必须在其他部分被解决之前解决,就像在餐厅服务员要端菜就必须有厨师做好了菜.在任务协作时,可以让任务自身挂起,直至某些外部条件发生变化,表示是时候让这个任务向前推动了为止. wait/notify wait方法会在等待外部

线程协作---生产者消费者模式之“管程法”实现

1 package cn.ftf.threadcooperation; 2 /** 3 * 协作模型:生产者消费者模式实现方式一:管程法,借助一个缓冲区 4 * @author 房廷飞 5 * 6 */ 7 8 public class CoTest01 { 9 public static void main(String[] args) { 10 SyContainer sy=new SyContainer(); 11 Productor pro=new Productor(sy); 12 p

Java多线程-同步:synchronized 和线程通信:生产者消费者模式

大家伙周末愉快,小乐又来给大家献上技术大餐.上次是说到了Java多线程的创建和状态|乐字节,接下来,我们再来接着说Java多线程-同步:synchronized 和线程通信:生产者消费者模式. 一.同步:synchronized 多个线程同时访问一个对象,可能造成非线程安全,数据可能错误,所谓同步:就是控制多个线程同时访就是控制多线程操作同一个对象时,注意是同一个对象,数据的准确性, 确保数据安全,但是加入同步后因为需要等待,所以效率相对低下. 如:一个苹果,自己一个人去咬怎么都不会出问题,但是

11.9-全栈Java笔记: 线程并发协作(生产者/消费者模式)

多线程环境下,我们经常需要多个线程的并发和协作.这个时候,就需要了解一个重要的多线程并发协作模型"生产者消费者模式". 什么是生产者? 生产者指的是负责生产数据的模块(这里模块可能是:方法.对象.线程.进程). 什么是消费者? 消费者指的是负责处理数据的模块(这里模块可能是:方法.对象.线程.进程). 什么是缓冲区? 消费者不能直接使用生产者的数据,它们之间有个"缓冲区".生产者将生产好的数据放入"缓冲区",消费者从"缓冲区"

Java线程:并发协作-生产者消费者模型

对于多线程程序来说,不管任何编程语言,生产者消费者模型都是最经典的. 实际上,准确的说应该是"生产者-消费者-仓储"模型,离开了仓储,生产者消费者模型就显得没有说服力了. 对于此模型,应该明确以下几点: 生产者仅仅在仓储未满时候生产,仓满则停止生产. 消费者仅仅在仓储有产品时候才能消费,仓空则等待. 当消费者发现仓储没有产品的时候会通知生产者生产. 生产者在生产出可消费产品时候,应该通知消费者去消费. 此模型将要结合java.lang.Object的wait与notify,notify

Java多线程之并发协作生产者消费者设计模式

两个线程一个生产者个一个消费者 需求情景 两个线程,一个负责生产,一个负责消费,生产者生产一个,消费者消费一个 涉及问题 同步问题:如何保证同一资源被多个线程并发访问时的完整性.常用的同步方法是采用标记或加锁机制 wait() / nofity() 方法是基类Object的两个方法,也就意味着所有Java类都会拥有这两个方法,这样,我们就可以为任何对象实现同步机制. wait()方法:当缓冲区已满/空时,生产者/消费者线程停止自己的执行,放弃锁,使自己处于等等状态,让其他线程执行. notify

线程的生产者消费者问题

package xiancheng;/** * wait() 等待 ,释放锁 sleep 不释放锁 * @author User * */ public class lianxi20 { //t 生产者生产 通知消费 f 消费者消费 通知生产 private boolean flag=true; //模拟生产的物品 private String picString; //生产 public synchronized void play(String picString){ //当flag为fal

Java 线程池 +生产者消费者+MySQL读取300 万条数据

1.1需求 数据库300 万条用户数据 ,遍历获取所有用户, 各种组合关联, 获取到一个新的json ,存到redis 上. 1.2 难点 数据库比较多, 不可能单线程查询所有的数据到内存. 1.3解决办法 多线程读取, 生产者 每次获取200 条数据, 消费者去消费.(这里 主要是根据MySQL分页去获取下一个200 条数据) 1.4 代码 1.4.1 调用方法 /** * 线程启动 */ public void update() { //redis操作类 HashRedisUtil redi

java线程之生产者消费者

看了毕向东老师的生产者消费者,就照着视频参考运行了一下,感觉还好 这个值得学习的是条理特别清晰: ProducterConsumerDemo.java中,一个资源类Resources,生产者消费者都可以访问的到. 生产者类Producter,消费者Consumer都实现了Runnable接口,在其中的run方法中实现重载,对共享资源进行生产和消费 优化: 如果以后需要加入项目中,对ProducterConsumerDemo类中加一个构造方法,public ProducterConsumerDem