Java学习day32
生产与消费者问题:假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者从仓库中取走产品;如果仓库中没有产品,生产者就将产品放入仓库,否则就停止生产等待;如果仓库中有产品,消费者就取走,否则就等待生产者生产
生产者和消费者共享同一个资源,并且生产者和消费者之间相互依赖,互为条件
Java提供了解决线程之间通信问题的方法:wait() //表示线程一直等待,知道其他线程通知,与sleep不同,会释放锁
wait(long timeout) //指定等待的毫秒数
notify() //唤醒一个处于等待状态的线程
notifyAll() //唤醒同一个对象上所有调用wait()方法的线程,优先级别高的线程优先调度
注意:以上均是Object类的方法,都只能在同步方法或者同步代码块中使用,否则会抛出异常IllegalMonitorStateException
解决办法:1.加入缓冲池,消费者和生产者都在缓冲池里操作
1 package com.Cra2iTeT.Demo03;
2
3 public class test1 {
4 public static void main(String[] args) {
5 Container container = new Container();
6 new Producer(container).start();
7 new Consumer(container).start();
8 }
9 }
10
11 class Producer extends Thread {
12 Container container;
13
14 public Producer(Container container) {
15 this.container = container;
16 }
17
18 @Override
19 public void run() {
20 for (int i = 0; i < 100; i++) {
21 container.f1(new Product(i));
22 System.out.println("生产了" + i + "只鸡");
23 }
24 }
25 }
26
27 class Consumer extends Thread {
28 Container container;
29
30 public Consumer(Container container) {
31 this.container = container;
32 }
33
34 @Override
35 public void run() {
36 for (int i = 0; i < 100; i++) {
37 System.out.println("消费了" + container.f2().id + "只鸡");
38 }
39 }
40 }
41
42 class Product {
43 int id;
44 public Product(int id) {
45 this.id = id;
46 }
47 }
48
49 class Container {
50 Product[] products = new Product[100];
51 int count = 0;
52
53 public synchronized void f1(Product product) {
54 if (count == 10) {
55 try {
56 this.wait();
57 } catch (InterruptedException e) {
58 e.printStackTrace();
59 }
60 }
61 products[count] = product;
62 count++;
63 this.notifyAll();
64 }
65
66 public synchronized Product f2() {
67 if (count == 0) {
68 try {
69 this.wait();
70 } catch (InterruptedException e) {
71 // TODO Auto-generated catch block
72 e.printStackTrace();
73 }
74 }
75 count--;
76 Product product = products[count];
77 this.notifyAll();
78 return product;
79 }
80 }
2.加入信号标识,指定信号标识下由指定的线程操作
1 package com.Cra2iTeT.Demo03;
2
3 public class test2 {
4 public static void main(String[] args) {
5 TV tv = new TV();
6 new Player(tv).start();
7 new Watcher(tv).start();
8 }
9 }
10
11 class Player extends Thread {
12 TV tv;
13
14 public Player(TV tv) {
15 this.tv = tv;
16 }
17
18 @Override
19 public void run() {
20 for (int i = 0; i < 20; i++) {
21 if (i % 2 == 0) {
22 this.tv.play("青海摇");
23 } else {
24 this.tv.play("西安摇");
25 }
26 }
27 }
28 }
29
30 class Watcher extends Thread {
31 TV tv;
32
33 public Watcher(TV tv) {
34 this.tv = tv;
35 }
36
37 @Override
38 public void run() {
39 for (int i = 0; i < 20; i++) {
40 tv.watch();
41 }
42 }
43 }
44
45 class TV {
46 String voice;
47 boolean flag = true;
48
49 public synchronized void play(String voice) {
50 if (!flag) {
51 try {
52 this.wait();
53 } catch (InterruptedException e) {
54 e.printStackTrace();
55 }
56 }
57 System.out.println("演员表演了:" + voice);
58 this.notifyAll();
59 this.voice = voice;
60 this.flag = !this.flag;
61 }
62
63 public synchronized void watch() {
64 if (flag) {
65 try {
66 this.wait();
67 } catch (InterruptedException e) {
68 e.printStackTrace();
69 }
70 }
71 System.out.println("观看了:" + voice);
72 this.notifyAll();
73 this.flag = !this.flag;
74 }
75
76 }
明天学习线程池,总结多线程的学习过程
Java学习day32的更多相关文章
- 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁
什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...
- 0035 Java学习笔记-注解
什么是注解 注解可以看作类的第6大要素(成员变量.构造器.方法.代码块.内部类) 注解有点像修饰符,可以修饰一些程序要素:类.接口.变量.方法.局部变量等等 注解要和对应的配套工具(APT:Annot ...
- 分享篇——我的Java学习路线
虽然之前我是开发出身,但是我学习的语言是Objective-c,这个语言使用起来范围比较窄,对于自动化学习来说也是无用武之地,所以我自己学习了Java,对于一个有开发经验的人来说学习一门新语言相对来说 ...
- Java学习笔记(04)
Java学习笔记(04) 如有不对或不足的地方,请给出建议,谢谢! 一.对象 面向对象的核心:找合适的对象做合适的事情 面向对象的编程思想:尽可能的用计算机语言来描述现实生活中的事物 面向对象:侧重于 ...
- Java学习心得之 HttpClient的GET和POST请求
作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 Java学习心得之 HttpClient的GET和POST请求 1. 前言2. GET请求3 ...
- 0032 Java学习笔记-类加载机制-初步
JVM虚拟机 Java虚拟机有自己完善的硬件架构(处理器.堆栈.寄存器等)和指令系统 Java虚拟机是一种能运行Java bytecode的虚拟机 JVM并非专属于Java语言,只要生成的编译文件能匹 ...
- 0030 Java学习笔记-面向对象-垃圾回收、(强、软、弱、虚)引用
垃圾回收特点 垃圾:程序运行过程中,会为对象.数组等分配内存,运行过程中或结束后,这些对象可能就没用了,没有变量再指向它们,这时候,它们就成了垃圾,等着垃圾回收程序的回收再利用 Java的垃圾回收机制 ...
- 0028 Java学习笔记-面向对象-Lambda表达式
匿名内部类与Lambda表达式示例 下面代码来源于:0027 Java学习笔记-面向对象-(非静态.静态.局部.匿名)内部类 package testpack; public class Test1{ ...
- 0025 Java学习笔记-面向对象-final修饰符、不可变类
final关键字可以用于何处 修饰类:该类不可被继承 修饰变量:该变量一经初始化就不能被重新赋值,即使该值跟初始化的值相同或者指向同一个对象,也不可以 类变量: 实例变量: 形参: 注意可以修饰形参 ...
随机推荐
- Python:range、np.arange和np.linspace
1. range range是python内置的一个类,该类型表示一个不可改变(immutable)的数字序列,常常用于在for循环中迭代一组特殊的数,它的原型可以近似表示如下: class rang ...
- Matplotlib库基础_一
Matplotlib库基础 •pyplot绘制坐标 plt.plot(x,y,format_string,**kwargs) x:x轴数据,列表或数组,可选 y:y轴数据,列表或数组 format_s ...
- WebGL 的 Hello World
本文整理自 div 侠于 凹凸 2022 年技术分享,简单介绍了 WebGL 画一个基础图形的流程,希望你了解之后,在使用 3d 渲染库的时候可以少点迷糊. 四种常用的页面绘图工具 关于h5页面的图形 ...
- Python 字典(键值对)
Python 字典(键值对) 创建字典 特性:字典中的键不能变,而且唯一 格式:变量名={"键1":值1,"键2":值2} 函数 作用 dict() 强制转换为 ...
- SpringMVC源码解读 - RequestMapping注解实现解读
SpringMVC源码解读 - RequestMapping注解实现解读 - RequestCondition体系 https://www.cnblogs.com/leftthen/p/520840 ...
- Spring Data Jpa 更新操作
第一步,通过Repository对象把实体根据ID查询出来 第二部,往查出来的实体对象进行set各个字段 第三步,通过Repository接口的save方法进行保存 保存和更新方式(已知两种) 第一种 ...
- BTree和B+Tree 简单区别
本篇作用于各种树之间的区别,非算法详细介绍,只是给我们这种非科班出身的一种大概的印象,现在网上更多是讲各种树的怎么实现的细节问题,本篇不涉及那么高深,如果详细了解可以查阅他人的资料,很多大神已经说的很 ...
- 什么是Hystrix断路器?我们需要它吗?
由于某些原因,employee-consumer公开服务会引发异常.情况下使用Hystrix我们定义了回退方法.如果在公开服务中发生异常,则回退方法返回一些默认值 . 如果firstPage metho ...
- 动态JDK代理方式-实现类增强
需求描述: 抽取dao层开启和提交事物交由代理类一并执行 分析: 假如UserDao接口中有很多方法,例如addUser().deleteUser().updateUser()等等,需要频繁的和数据库 ...
- C++模板学习之优先队列实现
转载:https://www.cnblogs.com/muzicangcang/p/10579250.html 今天将继续将强C++模板类的学习,同时为了巩固已经学习过的数据结构中有关优先队列的知识, ...