日志

  • 概述:专门用于记录程序运行的状态的技术;

  • 常见日志框架

    • logback

    • log4j

  • logback的使用步骤

    • 环境级别:

      • 下载并复制jar包到idea;
      • 复制配置文件到源码目录;
    • 代码级别:

      • 修改配置文件的内容;
      • 获取一个日志对象;
      • 面向对象,调用方法;
  • 注意事项

  1. 配置文件的名称和路径必须按框架的要求写和存;(必须放在源码目录下且名称是 logback.xml)
  2. 获取日志对象的时候,注意包;

参考代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
logback日志入门
*/
public class TestLogBack {
// 利用工具,获取一个日志对象
public static final Logger LOG= LoggerFactory.getLogger("TestLogBack");

public static void main(String[] args) {
// 利用 log对象 调用各种级别 的日志方法,就可以输出日志的内容了
System.out.println("正常代码1");
LOG.info("第一行代码走完了,没有出问题...");
System.out.println("正常代码2");
LOG.debug("第2行走完了,,,,debug级别");
System.out.println("正常代码3");
LOG.error("严重问题,代码走完了");
}
}

日志级别

  • 作用

    • 程序员可以通过设置不同的级别,从而决定记录程序中的不同问题;
  • 具体级别

image-20230528161739165

程序中会记录指定的级别以及更高的级别的问题!!!

多线程

  • 概述

    • 所谓的线程就是代码执行的通道;一个代码执行通道就是单线程程序,多个代码执行通道就是多线程程序;
  • 应用场景

    • 多人聊天,多文件同时下载…等
  • 实现方式

    • java中有3种方式可以实现多线程;

方式1-继承Thread

  • 概述:Thread是java编写的专门用于描述线程的类,只要创建这个类的对象,或者继承这个线程类,我们就相当于拥有了一个线程对象了;

  • 代码实现方式

    • 自定义一个类继承Thread类;
    • 重写run方法,指定线程的任务;
    • 在测试类中创建自定义类的对象并调用start方法启动线程即可;

参考代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
练习多线程的创建方式1:

继承 Thread类
*/
public class MyThread extends Thread {
// 这个方法里面的代码,就是将来线程需要执行的 任务 (线程相当于是通道,马路),而run方法的内容就是这个通道内需要执行的代码,马路上的汽车
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("我们自定义的线程打印了数据:"+i);
}
}
}
package com.itheima.demo05_Thread_1;

public class Test {
public static void main(String[] args) {
// 1: 创建线程对象
MyThread m1 = new MyThread();
// 2: 让我们的线程执行起来,一旦m1这个线程启动成功了,无论m1线程内的任务是否执行完了,都不影响main方法继续往下执行其他的代码;
m1.start();
// 3: 让main也打印100个数据
for (int i = 0; i < 100; i++) {
System.out.println("mian:"+i);
}
}
}

方式2-实现Runnable接口

  • 概述
    • 我们自定义的类,实现接口,仅仅算术一个任务类,将来可以将该类的对象,作为线程的参数传递进去,让线程执行这个任务即可;

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 这个类目前只是一个任务类,等待线程执行它
public class MyRun implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("第二种方式创建的单纯的任务:"+i);
}
}
}
/*
利用java的Thread类,创建出一个线程对象,并将我们提前准备的任务对象,交给线程对象,让线程执行我们准备的任务
*/
public class MyTest02 {
public static void main(String[] args) {
// 1: 创建任务对象
MyRun rw = new MyRun();
// 2: 创建线程对象,,并将我们提前准备的任务对象,交给线程对象,让线程执行我们准备的任务
Thread t = new Thread(rw);
// 3: 开启线程
t.start();
// 4: mian执行任务
for (int i = 0; i < 100; i++) {
System.out.println("main:"+i);
}
}
}

方式3-实现Callable接口

  • 概述

    • 程序员可以写一个带返回值的任务类,只需要实现 Callable接口即可,但是这个接口无法直接和线程绑定,需要借助 FutureTask 类中转才可以,将来也可以面向 FutureTask 类的对象,获取线程的结果;
  • FutureTask的常用方法

image-20230528174125314

参考代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*
带返回值的任务类
*/
public class MyCall implements Callable<Integer> {
@Override
public Integer call() throws Exception {
// 模拟计算需要3秒的时间
System.out.println("模拟计算中....");
Thread.sleep(3000);
System.out.println("模拟计算完....");
return 666;
}
}

public class Test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 1: 创建带返回值的任务对象
MyCall my = new MyCall();
// 2: 需要将my 任务对象包装成 FutureTask对象
FutureTask<Integer> task = new FutureTask<>(my);
// 3: 创建线程对象,并绑定 task
new Thread(task).start();
System.out.println("模拟main已经开启线程完毕...");
// 4: 找中间人要结果
Integer integer = task.get();
System.out.println("mian得到的结果是:"+integer);
}
}