2021年8月19日
1.生产者消费者模式
2.反射
3.单例模式
1.生产者消费者模式【模型】【偏难】
就是咱们昨天将的wait和notify
RabbitMQ 以后会学第三阶段
消息队列
1.1生活中实际案例的分析
厂家 鸿星尔克
生产者 鸿星尔克的生产厂家
消费者 龙飞
有几个角色?两个一个是生产者,一个消费者
龙飞要去消费,想去购买一双鸿星尔克的鞋。结果鸿星尔克厂家没货,龙飞需要进入到等待状态,鸿星尔克进入生产状态,开始加班加点的生产。生产好以后,告诉消费者(龙飞),来来你可以购买le。
1.2生产者消费者图例
消费者有两种情况:
1.厂家没货,消费者需要等待(阻塞)
2.厂家有货,消费者直接消费
生产者有两种情况:
1.没货,生产者需要生产
2.有货,进入到阻塞状态
1.3需要解决哪些问题?
1、如何让一个商品成为两个线程的共享资源?
创建一个商品类,在生产者和消费者类下面定义一个成员变量,使用构造方法进行初始化。
2、如果两个线程没有加锁的话,会导致代码的错乱
加锁,对商品进行加锁
写代码的思路:
1.Goods类,线程之间共享的资源
2.生产者类 是一个线程
3.消费者类 是另外一个线程
1
消费者购买了:法拉利,价格为:56.0
3
2
生产者生产了:奥迪A8,价格为:200.0
4
消费者购买了:奥迪A8,价格为:200.0
生产者生产了:保时捷,价格为:300.0
消费者购买了:保时捷,价格为:300.0
生产者生产了:奥迪A8,价格为:200.0
分析执行结果:
打印了1 指向了Productor这个线程里面的else代码 proDuctor这个线程抢到了cpu
goods.wait() Product线程阻塞了,不向下走了
生产者线程阻塞,消费者线程抢到cpu了 Customer这个线程
System.out.println("消费者购买了:" +goods.getName()+",价格为:"+ goods.getPrice()); 消费者购买了:法拉利,价格为:56.0
这个标记是true 没货需要生产。
生产者线程没有抢到cpu,还是消费者抢到了cpu
执行了消费者下面else 唤醒了消费者
会打印3 消费者(Customer)阻塞,生产者(Productor)抢到cpu
会打印2
System.out.println("生产者生产了:"+goods.getName()+ ",价格为:" + goods.getPrice());生产者生产了:奥迪A8,价格为:200.0
唤醒了消费者,
会打印4 消费者抢到cpu 消费者购买了:奥迪A8,价格为:200.0 标记为true
生产者抢到了cpu 打印了生产者生产了:保时捷,价格为:300.0
消费者抢到了cpu 打印了消费者购买了:保时捷,价格为:300.0
生产者抢到了cpu 打印了奥迪A8,价格为:200.0
最后的情况是 凑巧了,生产一个(生产者线程),消费一个(消费者线程交替在执行)
要分析执行的结果,我相信,我把这个代码发给大家话,你们的执行的结果和我不一样
但是你必须知道是怎么执行的。你们尝试分析一下这个结果,确实有点难。
我也你不知道是消费者线程先抢到还是生产者线程先抢到?这个是未知数,所以咱们打印的结果是不一样的。
2.反射【重点】
作用:咱们以后会封装一些类,一些方法,等有可能会遇到反射
2.1反射的简单的介绍
java的反射是我们在车哪个系运行的过程中可以动态的获取类的属性,构造方法,方法,父类,接口等内部的信息机制。反射的本质反着来。咱们new一个对象的时候,实际上是由java虚拟机根据Class类对象在运行的时候构建出来的。反射通过Class类对象获取定义的信息(有属性吗,方法,构造方法,等)
换句话说:就是换一种方式获取类对象的属性,方法,父类,接口等。
2.2反射原理的示意图
咱们之前是直接new一个对象出来,然后操作属性,方法等。现在用了反射以后,需要借助于.class文件获取属性和方法。换一种方式获取类对象的属性,方法,父类,接口等。
2.3获取Class对象【.class】
javac这个命令将.java 文件编译成.class文件,name这个.class文件就会包含对类原始定于的信息。属性,方法,构造方法等,。.class文件在运行的时候,会被classLoader加载到咱们的jvm里面。当一个.class文件被加载以后,JVM随即生成一个Class对象
如何创建出来Class对象?有三种方式
1.static Class forName(String name);
静态方法,通过class的调用,传入的参数是一个完整的类名(包名+类名)。
获取到了所对应的Class对象
2.Class 类名.class
通过类名获取Class对象
3.Class 类对象.getClass();
获取class对象
package com.qfedu.b_reflect;
//1.获取Class对象
public class Demo2 {
public static void main(String[] args) throws ClassNotFoundException {
//.class文件的对象
//Person.class文件对象
//Person person = new Person(); 直接获取
//反射 获取的第一种写法
Class<?> aClass = Class.forName("com.qfedu.b_reflect.Person");
System.out.println(aClass);
//通过类名获取 .class文件对象 第二种写法
Class<Person> class1 = Person.class;
System.out.println(class1);
//通过类对象来获取Class对象
Class<?> class2 = new Person().getClass();
System.out.println(class2);
}
}
2.4获取Constructor类对象【构造方法】
Constructor[] getConstractors();
获取当前类内所有的非私有化的构造方法。
Constructor[] getDeclaredConstructors();
获取当前类下面的所有构造方法
Constructor getConstructor(Class .... initParameterType);
通过构造方方法的参数,获取所对应非私有化构造方法
Constructor getDeclaredConstructor(Class ... initParameterType);
通过传递构造方法的参数,获取对应的额私有化的构造方法
以上的方法都是通过Class对象调用的
以下的方法是通过Constructor对象调用的
Object newInstance(Object .... param);
package com.qfedu.b_reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Demo3 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//1.先获取Class对象?为什么要先获取CLass类对象?
Class<?> aClass = Class.forName("com.qfedu.b_reflect.Person");
//2.需要使用类对象,获取构造方法
//获取多个公开的构造方法,有两个构造方法
Constructor<?>[] constructors = aClass.getConstructors();
//System.out.println(constructors);
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);//打印3个
}
System.out.println("===========");
Constructor<?>[] constructors2 = aClass.getDeclaredConstructors();
for (Constructor<?> constructor : constructors2) {
System.out.println(constructor);//打印3个
}
//能不能获取指定的非私有化的构造方法对象
System.out.println("**************");
//getConstructor这个方法没有传参数,获取的是无参数的构造方法
Constructor<?> constructor = aClass.getConstructor(null);
System.out.println(constructor);
//String.class 获取的是String类的Class对象
//这个构造方法,是带有String参数的构造方法
Constructor<?> constructor1 = aClass.getConstructor(String.class);
System.out.println(constructor1);
Constructor<?> constructor2 = aClass.getConstructor(int.class, String.class);
System.out.println(constructor2);
System.out.println("-----------------");
//相获取私有化的对应构造方法
Constructor<?> constructor3 = aClass.getDeclaredConstructor(int.class);
System.out.println(constructor3);