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关键字可以用于何处 修饰类:该类不可被继承 修饰变量:该变量一经初始化就不能被重新赋值,即使该值跟初始化的值相同或者指向同一个对象,也不可以 类变量: 实例变量: 形参: 注意可以修饰形参 ...
随机推荐
- 基于Spring Cache实现二级缓存(Caffeine+Redis)
一.聊聊什么是硬编码使用缓存? 在学习Spring Cache之前,笔者经常会硬编码的方式使用缓存. 我们来举个实际中的例子,为了提升用户信息的查询效率,我们对用户信息使用了缓存,示例代码如下: @A ...
- 端口转发工具--lcx
简介 lcx是一款强大的内网端口转发工具,用于将内网主机开放的内部端口映射到外网主机(有公网IP)任意端口.它是一款命令行工具,当然也可以在有权限的webshell下执行,正因如此lcx常被认为是一款 ...
- SQL注入工具sqlmap的使用
sqlmap使用 测试注入点 sqlmap -u "URL" 爆数据库 sqlmap -u "URL" --dbs 查看当前库 sqlmap -u " ...
- c# / .net wFramework winform 之运行后的窗体窗口可拖动操作
学习winform 的同志们可能会有这样的提问,我运行起来的窗体或者窗口该如何实现可拖动呢?今天它来了 思路:可以给窗体增加一个进度条(progressBar控件) 全局定义这几个变量: long p ...
- BUAA 2021-2022毛概复习资料
2021-2022年毛概期末主观题复习范围,参考2022版教材和课程组官方PPT,原文太过敏感,所以贴出代码大家自己run #include <stdio.h> unsigned arti ...
- 基于COLA架构的电商财务系统-总
财务 清算-clearing 对账-check 结算-settle 平账-correct 划拨-remit 包划分 按照COLA规则进行划分,综合考虑功能和领域两个维度包结构定义 技术参考 dddpl ...
- http多路复用?
Keep-Alive: Keep-Alive解决的核心问题:一定时间内,同一域名多次请求数据,只建立一次HTTP请求,其他请求可复用每一次建立的连接通道,以达到提高请求效率的问题.这里面所说的一定时间 ...
- Struts2的Action中获取request对象的几种方式?
通过ActionContext.getSession获取 通过ServletActionContext.getRequest()获取 通过SessionAware接口注入 通过ServletReque ...
- JVM中的常量池
在Java的内存分配中,总共3种常量池: ref:https://blog.csdn.net/zm13007310400/article/details/77534349 1.字符串常量池(Strin ...
- 什么是openssl?
在计算机网络上,OpenSSL是一个开放源代码的软件库包,应用程序可以使用这个包来进行安全通信,避免窃听,同时确认另一端连接者的身份.这个包广泛被应用在互联网的网页服务器上.