IT自学第二十天

XML

Element提供的方法

代码演示:

java 复制代码
public class Dom4JTest1 {
    public static void main(String[] args) throws DocumentException {
        //目标:解析XML文件,使用Dom4j框架
        //1、创建一个SaxReader解析对象
        SAXReader saxReader = new SAXReader();

        //2、把xml文件读成一个Document文档对象
        Document document = saxReader.read("day11-special-file-log-code\\src\\Contact.xml");

        //3、文档对象中包含了XML的全部数据,提供了方法获取数据
        Element rootElement = document.getRootElement();
        System.out.println(rootElement.getName());

        //4、提取子元素对象
        List<Element> sonEles = rootElement.elements();
        for (Element sonElement : sonEles) {
            System.out.println(sonElement.getName());
        }
        System.out.println("---");

        //指定获取单个子元素对象
        Element userEle = rootElement.element("user");
        System.out.println(userEle.elementText("name"));

        Element contactEle = rootElement.element("contact");
        System.out.println(contactEle.elementText("name"));

        //5、提取了元素的属性对象
        Attribute idAttr = contactEle.attribute("id");
        //  属性名称  "id"
        System.out.println(idAttr.getName());
        System.out.println(idAttr.getValue());

        //直接拿属性值
        System.out.println(contactEle.attributeValue("id"));

        //6、文本值
        //通过父元素拿到子元素的文本值
        System.out.println(contactEle.elementText("name"));
        System.out.println(contactEle.elementTextTrim("name"));

        //先拿到元素对象,再提取文本值
        Element emailEle = contactEle.element("email");
        System.out.println(emailEle.getText());
        System.out.println(emailEle.getTextTrim());
    }
}

6、XML解析案例

需求:利用Dom4j框架,将contacts.xml文件中的联系人数据,解析出来,封装成List集合,并遍历输出;

代码演示:

java 复制代码
public class Dom4JTest2 {
    public static void main(String[] args) throws DocumentException {
        //目标:解析XML文件,使用Dom4j框架
        //1、创建一个SaxReader解析对象
        SAXReader saxReader = new SAXReader();

        //2、把xml文件读成一个Document文档对象
        Document document = saxReader.read("day11-special-file-log-code\\src\\Contact.xml");

        //3、文档对象中包含了XML的全部数据,提供了方法获取数据
        Element rootElement = document.getRootElement();

        //4、准备一个联系人集合存储联系人对象
        List<Contact> contacts = new ArrayList<>();

        //5、提取全部以及联系人元素对象
        List<Element> sonEles = rootElement.elements("contact");

        //6、遍历子元素对象
        for (Element sonEle : sonEles) {
            //7、每个子元素是一个联系人对象,创建联系人对象,封装数据
            Contact contact = new Contact();
            //注入数据
            contact.setId(Integer.valueOf(sonEle.attributeValue("id")));
            contact.setName(sonEle.elementTextTrim("name"));
            contact.setGender(sonEle.elementTextTrim("gender").charAt(0));
            contact.setEmail(sonEle.elementTextTrim("email"));
            contacts.add(contact);
        }
        for (Contact contact : contacts) {
            System.out.println(contact);
        }
    }
}

7、XML的创建

推荐直接把程序里的数据拼接成XML,然后用IO流写出去!

代码演示:

java 复制代码
public class Dom4JTest3 {
    public static void main(String[] args) throws Exception {
        //目标:将数据写入到xml文件
        StringBuilder sb = new StringBuilder();
        sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n");
        sb.append("<user>\r\n");
        sb.append("\t<name>").append("张三").append("</name>\r\n");
        sb.append("\t<age>").append("12").append("</age>\r\n");
        sb.append("\t<sex>").append("男").append("</sex>\r\n");
        sb.append("</user>\r\n");

        PrintStream ps = new PrintStream("day11-special-file-log-code/src/users.xml");
        ps.println(sb);
        ps.close();
    }
}

8、约束

什么是约束XML文件的书写?

  • 就是限制XML文件只能按照某种格式进行书写;

约束文档

  • 专门用来限制XML书写格式的文档,比如:限制标签、属性应该怎么写。

约束文档的分类

  • DTD文档
  • Schema文档

XML文档约束-DTD的使用

需求:利用DTD约束文档,约束一个XML文件的编写。

注意:dtd,可以约束XML文件的编写;不能约束具体的数据类型。

XML文档约束-schema的使用

可以约束XML文件的编写、和数据类型

需求:利用schema文档约束,约束一个XML文件的编写。

注意:域名与数据类型的编写。

9、日志概述

什么是日志?

  • 好比生活中的日记,可以记录你生活中的点点滴滴;
  • 程序中的日志,通常就是一个文件,里面记录的是程序运行过程中的各种信息。

日志技术:

  • 可以将系统执行的信息,方便的记录到指定的位置(控制台、文件中、数据库中)。
  • 可以随时以开关的形式控制日志的启停,无需侵入到源代码中去进行修改。

日志框架:牛人或者第三方公司已经做好的实现代码,后来者直接可以拿去使用;

Logback是基于slf4j的日志规范实现的框架。

日志技术的体系结构

Logback日志框架官方网站:https://logback.qos.ch/

Logback日志框架有一下几个模块:

想使用Logback日志框架,至少需要在项目中整合如下三个模块:

10、日志技术框架搭建

需求:使用Logback日志框架,记录系统的运行信息;

实现步骤:

代码演示:

java 复制代码
public class Test {
    public static final Logger LOGGER = LoggerFactory.getLogger("Test.class");
    public static void main(String[] args) {
        //目标:1、创建一个Logback框架的Logger日志对象,来记日志;
        try{
            LOGGER.info("chu方法开始了~~");
            chu(10,5);
            LOGGER.info("chu方法成功了~~");
        }catch(Exception e){
            LOGGER.error("chu方法执行失败,出现异常: "+e.getMessage());
        }
    }
    public static void chu(int a,int b){
        LOGGER.debug("参数a: "+a);
        LOGGER.debug("参数b: "+b);
        int c = a/b;
        LOGGER.info("c= " + c);
    }
}

11、日志级别

什么是日志级别?

  • 日志级别指的是日志信息的类型,日志都会分级别,常见的日志级别如下(优先级依次升高):

为什么要学习日志级别?

  • 只有日志的级别是大于或等于核心配置文件配置的日志级别,才会被记录,否则不记录。

注意:all全部打印;error则只打印error及以上的级别日志;不想打印为off。


多线程


1、多线程创建方式一

什么是线程?

  • 线程是一个程序内部的一条执行流程。
  • 程序中如果只有一条执行流程,那这个程序就是单线程的程序;

多线程是什么?

  • 多线程是指从软硬件上实现的多条执行流程的技术(多条线程由CPU负责调度执行)。

多线程用在哪里,有什么好处?

12306多用户同时购买票;百度网盘同时上传与下载;消息的发送与接收;

如何在程序中创建出多条线程?

  • Java是通过java.lang.Thread类的对象来代表线程的。

多线程的创建方式一:继承Thread类

方法一优缺点:

优点:编码简单

缺点:线程类已经继承了Thread,无法继承其他类,不利于功能的扩展。

代码演示:

java 复制代码
public class ThreadDemo1 {
    //注意:main方法本身就是由一条主线程负责执行的
    public static void main(String[] args) {
        //目标:掌握线程的创建方式一:集成Thread类。
        //3、创建线程对象代表具体的线程
        Thread t = new MyThread();
        //4、启动线程;会自动执行线程的run方法
        t.start();
        //  t.run();   此时就会一直子线程先跑。还是单线程,并没有去CPU注册线程
        for (int i = 0; i < 4; i++) {
            System.out.println("main线程输出: "+i);
        }
    }
}

//1、定义一个类继承Thread类,成为线程类
class MyThread extends Thread{
    //2、重写run方法,声明线程要干的事情
    @Override
    public void run() {
        for (int i = 0; i < 4; i++) {
            System.out.println("子线程输出: "+i);
        }
    }
}

注意事项:

  1. 调用start方法,不调用run方法;
  2. 不要把主线程任务放在启动子线程之前。否则就相当于是一个单线程的效果了。

2、多线程创建方式二

实现Runnable接口

方法二的优缺点

优点:任务类只是实现接口,可以继续继承其他类,实现其他接口,扩展性强。

缺点:需要多一个Runnable对象。

代码演示:

java 复制代码
public class ThreadDemo2 {
    //注意:main方法本身就是由一条主线程负责执行的
    public static void main(String[] args) {
        //目标:掌握线程的创建方式一:集成Thread类。
        //3、创建线程对象代表具体的线程
        Runnable target = new MyRunnable();
        //4、启动线程;会自动执行线程的run方法
        new Thread(target).start();
        //  t.run();   此时就会一直子线程先跑。还是单线程,并没有去CPU注册线程
        for (int i = 0; i < 4; i++) {
            System.out.println("main线程输出: "+i);
        }
    }
}

//1、定义一个类继承Runable类,成为线程类
class MyRunnable implements Runnable{
    //2、重写run方法,声明线程要干的事情
    @Override
    public void run() {
        for (int i = 0; i < 4; i++) {
            System.out.println("子线程输出: "+i);
        }
    }
}

简化形式

匿名内部类

代码演示:

java 复制代码
public class ThreadDemo2_2 {
    //注意:main方法本身就是由一条主线程负责执行的
    public static void main(String[] args) {
        //目标:匿名内部类创建线程,Runnable
        //3、创建线程对象代表具体的线程
        //4、启动线程;会自动执行线程的run方法
        new Thread(()-> {
            for (int i = 0; i < 4; i++) {
                System.out.println("子线程输出"+i);
            }}).start();
        //  t.run();   此时就会一直子线程先跑。还是单线程,并没有去CPU注册线程
        for (int i = 0; i < 4; i++) {
            System.out.println("main线程输出: "+i);
        }
    }
}

3、多线程创建方式三

前两种线程创建方式都存在的一个问题

  • 假如线程执行完毕后有一些数据需要返回,他们重写的run方法均不能直接返回结果。

怎么解决这个问题?

  • JDK 5.0提供了Callable接口和FutureTask类来实现(多线程的第三种创建方式)。
  • 这种方式最大的优点:可以返回线程执行完毕后的结果。

多线程的第三种创建方式:利用Callable接口、FutureTask类来实现;

FutureTask的API

线程创建方式三的优缺点

优点:线程任务类只是实现接口,可以继续继承类和实现接口。扩展性强;可以在线程执行完毕后去获取线程执行的结果。

缺点:编码要复杂一点。

代码演示:

java 复制代码
public class ThreadDemo3 {
    public static void main(String[] args) {
        //目标:掌握多线程的创建方式三:可以返回线程执行完成值
        //3、创建Callable对象
        Callable<String> call = new MyCallable(100);
        //4、把Callable对象,封装成FutureTask对象
        //未来任务对象有两个作用:
        //  他是一个Runnable对象
        //  可以获取线程执行后的结果
        FutureTask<String> task = new FutureTask<>(call);
        //5、把未来任务对象交给线程对象
        Thread t = new Thread(task);
        //6、启动线程
        t.start();

        Callable<String> call2 = new MyCallable(200);
        FutureTask<String> task2 = new FutureTask<>(call2);
        Thread t2 = new Thread(task2);
        t2.start();

        try {
            //如果第一个线程没有执行完毕,会在这里等待第一个线程执行完毕后,再取结果
            String rs1 = task.get();
            System.out.println(rs1);
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            String rs2 = task2.get();
            System.out.println(rs2);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

//1、定义一个类实现Callable接口
class MyCallable implements Callable<String> {
    private int n;

    public MyCallable(int m) {
        this.n = m;
    }

    //2、重写call方法,声明任务和返回的结果
    @Override
    public String call() throws Exception {
        int sum = 0;
        for (int i = 0; i < n; i++) {
            sum += i;
        }
        return "子线程求和1-" + n + "的结果是" + sum;
    }
}

4、线程的API

Thread提供了很多与线程操作相关的方法

相关推荐
蒹葭玉树2 小时前
【C++上岸】C++常见面试题目--操作系统篇(第二十九期)
java·c++·面试
知识即是力量ol2 小时前
一次完整的 Spring Security JWT 鉴权链路解析
java·后端·spring·鉴权·springsecurity
子木鑫2 小时前
[SUCTF 2019] CheckIn1 — 利用 .user.ini 与图片马构造 PHP 后门并绕过上传检测
android·开发语言·安全·php
浅念-2 小时前
C语言——自定义类型:结构体、联合体、枚举
c语言·开发语言·数据结构·c++·笔记·学习·html
mirror_zAI2 小时前
C语言中的sscanf用法详解
c语言·开发语言
heartbeat..2 小时前
深入理解 JVM:从核心原理到实战应用
java·jvm·jdk·学习笔记
独自破碎E2 小时前
数组列表中的最大距离
java
猿小羽2 小时前
基于 Spring AI 与 Streamable HTTP 构建 MCP Server 实践
java·llm·spring ai·mcp·streamable http
大模型微调Online2 小时前
深度复盘:Qwen3-4B-Instruct-2507微调实战——打造“快思考、强执行”的 ReAct IoT Agent
java·后端·struts