day32-java

知识点补充

线程通信

生产者与消费者模型

测试类
package com.itheima.thread.communication_thread;


/**
 * 生产者和消费者模型
 * 需求:有三个厨师做包子和两个客人吃包子
 * 客人每次只能吃一个包子,桌上有包子时,客人就可以吃
 * 吃完叫厨师做,没包子就等
 * 桌上有包子厨师就等,没包子了厨师就做,做完叫客人吃
 */
public class Test {
    public static void main(String[] args) {
        new Cooker("厨师1").start();
        new Cooker("厨师2").start();
        new Cooker("厨师3").start();
        new Foodie("小明").start();
        new Foodie("小红").start();
    }
}
Foodie类
package com.itheima.thread.communication_thread;

public class Foodie extends Thread {
    public Foodie(String name) {
        super(name);
    }

    @Override
    public void run() {
        while (true){
            synchronized (Desk.class){
                if (Desk.count>0){
                    if (Desk.foodExist){
                        System.out.println(Thread.currentThread().getName()+"吃掉了一个包子");
                        Desk.foodExist = false;
                        Desk.count--;
                        System.out.println("包子总数剩余:"+Desk.count);
                        //使用什么当作锁,就要用什么去唤醒线程,让线程等待
                        Desk.class.notifyAll();
                    }else {
                        try {
                            Desk.class.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }else {
                    break;
                }
            }
        }
    }
}
Cooker类
package com.itheima.thread.communication_thread;

public class Cooker extends Thread {
    public Cooker(String name) {
        super(name);
    }

    @Override
    public void run() {
        while (true){
            synchronized (Desk.class){
                if (Desk.count>0){
                    if (Desk.foodExist){
                        try {
                            Desk.class.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }else {
                        System.out.println(Thread.currentThread().getName()+"做了一个包子");
                        Desk.foodExist = true;
                        Desk.class.notifyAll();
                    }
                }else{
                    break;
                }
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
Desk 类
package com.itheima.thread.communication_thread;

public class Desk {
    //定义食物存在标记
    public static boolean foodExist = false;
    //定义食物总数量
    public static int count = 10;
}

枚举

枚举的特点

1.所有枚举类都是Enum的子类
2.通过枚举类名.枚举项访问枚举项
3.每个枚举项其实就是一个枚举类的对象
4.枚举也是一个类,可以定义成员变量
5.枚举类的第一行必须写枚举项,当枚举项后面没有其他东西时,最后一个枚举项后面的分号可以省略,但不建议省略
6.枚举类可以有构造器,但必须用private修饰,且默认用private修饰,其用法也比较特殊:枚举(“”);
7.枚举类可以有抽象方法,但所有枚举项都必须重写所有抽象方法

枚举的方法

package com.itheima.demo04enum;

/**
 * 枚举的方法
 */
public class DemoEnum02 {
    public static void main(String[] args) {
        //1.String name()  返回枚举项的名称
        System.out.println(Name.X.name());
        System.out.println("----------------------");

        //2.int ordinal()  返回枚举项在枚举类中的索引
        System.out.println(Name.X.ordinal());
        System.out.println(Name.Y.ordinal());
        System.out.println(Name.Z.ordinal());
        System.out.println("----------------------");

        //3.int compareTo(E e)  比较两个枚举项,返回索引差值
        System.out.println(Name.Z.compareTo(Name.X));
        System.out.println("----------------------");

        //4.String toString()  返回枚举常量的名称
        System.out.println(Name.Z.toString());
        System.out.println("------------------------");

        //5.static <T> valueOf(class <T> type,String name)  获取指定枚举类中指定枚举项的值
        System.out.println(Enum.valueOf(Name.class, "Y"));
        System.out.println(Name.valueOf("X")==Name.X);
        System.out.println("--------------------------");

        //6.values()  获取所有枚举项
        Name[] values = Name.values();
        for (Name value : values) {
            System.out.println(value);
        }
    }
}
Name类
package com.itheima.demo04enum;

/**
 * 枚举实际上也是一个类,同样可以定义构造器,成员变量,但一般不这么做
 */
public enum  Name {
    //枚举项必须重写所有抽象方法
    X("李四"){
        @Override
        public void showName() {
            System.out.println(name);
        }
    },Y("王五"){
        @Override
        public void showName() {
            System.out.println(name);
        }
    },Z("张三"){
        @Override
        public void showName() {
            System.out.println(name);
        }
    };//枚举项后面写括号其实就是在调用枚举类的有参构造

    public String name;

    //空参构造,枚举类的构造器必须是private修饰的,默认也是private修饰
    private Name() {
    }

    //有参构造
    Name(String name){
        this.name = name;
    }

    //抽象方法
    public abstract void showName();
}

XML文件写入

package com.itheima.d6_write_xml;

import java.io.BufferedWriter;
import java.io.FileWriter;

/**
 * 往XML文件中写入数据
 * Dom4j提供的写入方法使用比较麻烦,这里使用StringBuilder来做
 */
public class Demo01 {
    public static void main(String[] args) {
        // 1、使用一个StringBuilder对象来拼接XML格式的数据。
        StringBuilder sb = new StringBuilder();
        sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n");
        sb.append("<book>\r\n");
        sb.append("\t<name>").append("从入门到跑路").append("</name>\r\n");
        sb.append("\t<author>").append("shifan").append("</author>\r\n");
        sb.append("\t<price>").append(999.99).append("</price>\r\n");
        sb.append("</book>");

        try (
                BufferedWriter bw = new BufferedWriter(new FileWriter("day14-xml/src/book.xml"));
        ){
            bw.write(sb.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

DTD约束文件

dtd语法规则

<!-- DTD语法规则
        定义元素规则:<!ELEMENT 元素名 元素类型)>
            简单元素:
            EMPTY:表示标签体为空
            ANY:表示标签体可以为空也可以不为空
            PCDATA:表示标签体为字符串
            复杂元素:
            直接写子元素名称.
                多个子元素可以使用,或者|隔开
                ","表示定义子元素的顺序
                "|"表示子元素只能出现任意一个
                "?"表示零次或一次
                "+"表示一次或多次
                "*"表示零次或多次
                不写默认表示出现一次
        定义属性的规则
            定义格式:<!ATTLIST 元素名称 属性名称 属性的类型 属性的约束>
            属性的类型:CDATA类型  字符串
            属性的约束:
                #REQUIRED 必需的
                #IMPLIED 非必需的
                #FIXED value 属性值是固定的
        -->
<!ELEMENT persons (person+)>
<!ELEMENT person (name,age)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ATTLIST person id CDATA #FIXED "1">

dtd的三种引入方式

引入本地约束文件
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 引入dtd约束,persons为根标签名,system表示引入的是本地约束,单引号内是路径 -->
<!DOCTYPE persons SYSTEM 'H:\JavaLearning\JavaSEAdvance\day14-xml\src\com\itheima\d1_xml_constraint\dtd\person.dtd'>
<persons>
    <person id="1">
        <name>shiafan</name>
        <age>30</age>
    </person>
    <person>
        <name>fan</name>
        <age>20</age>
    </person>
</persons>
xml文件内部引入
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 在XML文件内部引入dtd约束 -->
<!DOCTYPE persons [
        <!ELEMENT persons (person+)>
        <!ELEMENT person (name,age)>
        <!ELEMENT name (#PCDATA)>
        <!ELEMENT age (#PCDATA)>
        ]>
<persons>
    <person>
        <name>shiafan</name>
        <age>30</age>
    </person>
    <person>
        <name>fan</name>
        <age>20</age>
    </person>
</persons>
引入网络dtd
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 引入网络dtd约束 -->
<!DOCTYPE persons PUBLIC "DTD文件名称" "DTD文档URL">
<persons>
    <person>
        <name>shiafan</name>
        <age>30</age>
    </person>
    <person>
        <name>fan</name>
        <age>20</age>
    </person>
</persons>

schema约束文件

schema与dtd的区别

1.schema约束文件也是一个xml文件,符合xml语法,后缀名为.xsd
2.一个xml文件中可以引入多个schema约束文件,使用名称空间区分(名称空间类似Java包名
3.dtd里元素类型取值比较单一,常见的是#PCDATA类型,schema中可以支持很多数据类型
4.schema语法更复杂

编写schema文件

<?xml version="1.0" encoding="UTF-8" ?>
<!--根标签schema
    参数一:表示当前文件是一个约束文件,用于约束别的文件,同时此属性也对schema进行约束
    参数二:当前schema文件的名称空间,唯一的url地址,其他文件通过该名称空间引入该约束
    参数三:固定格式,表示当前schema文件是一个质量良好的文件-->
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.itheima.cn/javase"
        elementFormDefault="qualified">
<!-- 定义元素 -->
    <element name="persons">
<!--        表示元素为复杂元素-->
        <complexType>
<!--            表示子元素要按顺序定义-->
            <sequence maxOccurs="unbounded">
                <element name="person">
                    <complexType>
                        <sequence>
                            <element name="name" type="string"></element>
                            <element name="age" type="string"></element>
                        </sequence>
                        <!--定义属性-->
                        <attribute name="id" type="string" use="required"></attribute>
                    </complexType>
                </element>
            </sequence>
        </complexType>
    </element>
</schema>

引入schema文件

<?xml version="1.0" encoding="UTF-8" ?>
<!--     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"表示本文件被约束
         xmlns="http://www.itcast.cn"约束文件名称空间,表示被该文件约束
         xsi:schemaLocation="http://www.itcast.cn data.xsd"> 指定约束文件路径
         格式:xsi:schemaLocation="名称空间url 文件路径" 空格隔开
 -->
<persons xmlns="http://www.itheima.cn/javase"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.itheima.cn/javase person.xsd">
    <person id="1">
        <name>shiafan</name>
        <age>30</age>
    </person>
    <person id="2">
        <name>fan</name>
        <age>20</age>
    </person>
</persons>

类加载器

定义

负责将.class文件(物理存储的文件)加载到内存中去

类加载的时机

1.创建类的实例
2.调用类的方法
3.访问类或者接口的类变量,或为类变量赋值
4.使用反射方式强制创建某个类或接口的java.lang.class对象
5.初始化某个类的子类
6.直接使用java.exe命令来运行某个主类

简单来说就是,用到就加载,不用不加载

类加载的过程

加载->链接(验证->准备->解析)->初始化

加载:通过类的全限名获取类的二进制字节流,将字节流所代表的静态存储结构转化为运行时数据结构,在内存中生成一个代表这个类的java.lang.Class对象

验证:链接阶段的第一步,确保Class文件字节流中包含的信息符合当前虚拟机的要求,且不会危害虚拟机自身安全

准备:为类的类变量分配内存,赋值为null

解析:将类的二进制数据流中的符号引用替换成直接引用,如果类中用到了其他类,之前会将其他类替换为符号引用,此时需要找到对应的类,替换为直接引用

初始化:根据程序员的主观计划初始化类变量和其他资源

类加载器分类

启动类加载器,平台类加载器,系统类加载器

双亲委派模型

package com.ithaima.d5_classloader;

/**
 * 双亲委派模型
 */
public class Demo01 {
    public static void main(String[] args) {
        //获取系统类加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();

        //获取系统类加载器的父类-->平台类加载器
        ClassLoader platformClassLoader = systemClassLoader.getParent();

        //获取平台类加载器的父类-->启动类加载器
        ClassLoader bootstrapClassLoader = platformClassLoader.getParent();

        /*
        系统类加载器:jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc
        平台类加载器:jdk.internal.loader.ClassLoaders$PlatformClassLoader@79698539
        启动类加载器:null
         */
        System.out.println("系统类加载器:"+systemClassLoader);
        System.out.println("平台类加载器:"+platformClassLoader);
        System.out.println("启动类加载器:"+bootstrapClassLoader);
    }
}

类加载器的常用方法

package com.ithaima.d5_classloader;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * 类加载器的常用方法
 * public static ClassLoader getSystemClassLoader()  获取系统类加载器
 * public InputStream getResourceAsStream(String name)  加载某个资源文件
 */
public class Demo02 {
    public static void main(String[] args) throws IOException {
        //获取系统类加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();

        //获取资源文件字节输入流
        InputStream ras = systemClassLoader.getResourceAsStream("prop.properties");

        Properties properties = new Properties();
        properties.load(ras);
        System.out.println(properties);
    }
}

UUID类

import java.util.UUID;

public class UUIDDemo {
    public static void main(String[] args) {
        //生成一个随机且唯一的UUID对象
        UUID uuid = UUID.randomUUID();
        String replace = uuid.toString().replaceAll("-", "");
        //e6268fb7671448d3bab68a44298a02a2
        System.out.println(replace);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值