多线程

Posted Kirl z

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程相关的知识,希望对你有一定的参考价值。

1. 多线程

1.1 概念

线程是操作系统能够进行运算调度的最小单位,被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务

1.2 线程和进程的关系

  • 进程是包含线程
  • 进程是系统分配资源 (CPU, 内存) 的最小单位, 线程是系统调度 CPU 执行的最小单位
  • 同一个进程内的线程之间, 可以共享资源, 代价比较小 不同进程之间, 要共享数据, 需要进行进程通信

1.3 多线程的作用

提高效率 (尽可能充分利用系统资源: CPU)

需要注意的事项: 创建线程, 是一个比较耗时间和资源的

综合考虑:
同时执行指令 (任务量) + 创建线程数量 + 系统可用资源 (内存, CPU)

1.4 使用场景

一个时间点, 要同时做多件事情 (同时执行多行代码)
在这里插入图片描述
多线程的方式, 把以上内容, 按照时间范围, 规定好, 某个时间点, 要展示的图片, 播放的声音, 展示的文本

2. 内部类

(1) 匿名内部类
在一个方法中, new 类型 / 接口 () {} , () 指定构造方法, {} 指定要重写的方法
(2) 静态内部类
一个类的内部, 类似静态变量的方式, 定义一个类使用的时候, 和普通的类差不多

public class 匿名内部类 {
    public static void main(String[] args) {
        A a = new A(){// 匿名内部类,本质是A的子类,但不能等同A类型
            //可以重写方法,或不重写(继承)
            @Override
            public void pro() {
                System.out.println("pro");
            }
        };
        a.pro();//想打印pro

        B b = new B() {// 匿名内部类:B接口的实现类,不能等同于B
            @Override
            public void pro() {
                System.out.println("b pro");
            }
        };
        b.pro();//打印pro
    }

    //静态内部类
    static class A{
        public void pro(){
            System.out.println("a pro");
        };
    }
    //内部接口
    interface B{
        void pro();
    }
}

3. 多线程基础api

主要 api, 几乎都是对县城状态转变的操作

3.1 创建线程

  1. Thread: new 一个 Thread 类的子类; Thread 就是 java 中的线程
  2. Runnable: new 一个 Runnable 接口的子类, 传到 Thread 中执行; Runnable 是 java 中, 任务的概念, new 一个 Runnable, 就是定义一个任务的描述, 再传入 Thread 线程中执行
  3. Callable

3.1.1 常见的线程创建方式

1, 匿名内部类, 定义一个线程类, 并 new 创建出来, 重写 run 方法, 定义要执行的任务

//匿名内部类+Thread的方式创建一个线程
Thread t = new Thread(){
    @Override
    public void run() {//线程要执行的任务
        System.out.println("ok");
    }
};

继承 Thread 类

class Mythread extends Thread {
	@override
	public viod run() {
		System.out.println("thread ok");
	}
}

2, 使用 Runnbale 对象创建线程对象

Thread t = new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("tt ok");
    }
});

3, 使用 Runnbale 对象创建线程对象, 并命名

Thread t = new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("tt ok");
    }
},"t");

3.2 启动线程

start: 线程启动的方法 (启动以后, 才能表现并发, 并行的特性)

返回值类型方法
voidstart() 导致此线程开始执行; Java 虚拟机调用此线程的 run 方法

申请系统调度线程, 让 CPU 执行 (创建态 --> 就绪态), 如果线程获取 CPU 时间片, 就开始执行任务 (Thread 类中 run 方法就是任务的定义, 或者是 Runnable 对象中的 run 方法)

start 和 run 区别

  • start 会真正的启动一个线程, 和调用 start 方法所在的线程, 是并发并行执行
  • run 方法只是一个线程的任务定义, 如果直接调用 run 方法, 属于普通方法调用

3.2.1 理解线程执行时并发(并发 + 并行) 特性

public static void main(String[] args) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("子线程执行");
        }
    }, "子线程").start();
    System.out.println("main 线程执行");
}

//运行结果
main 线程执行
子线程执行

在这里插入图片描述
main 线程在 start() 时处于运行态, 继续指向打印语句, 几率是非常大的, 指向时间非常快
除非: 1. 异常 2. 时间片刚好用完

注意:

  • 子线程创建比较耗时, 系统调度也是需要一定时间
  • 整体看 main 线程和子线程同时并发并行执行打印, 最先执行的很大几率是main线程中的打印语句

以上是关于多线程的主要内容,如果未能解决你的问题,请参考以下文章

线程学习知识点总结

多个请求是多线程吗

python小白学习记录 多线程爬取ts片段

多线程编程

多线程编程

python多线程