多线程
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 创建线程
- Thread: new 一个 Thread 类的子类; Thread 就是 java 中的线程
- Runnable: new 一个 Runnable 接口的子类, 传到 Thread 中执行; Runnable 是 java 中, 任务的概念, new 一个 Runnable, 就是定义一个任务的描述, 再传入 Thread 线程中执行
- 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: 线程启动的方法 (启动以后, 才能表现并发, 并行的特性)
返回值类型 | 方法 |
---|---|
void | start() 导致此线程开始执行; 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线程中的打印语句
以上是关于多线程的主要内容,如果未能解决你的问题,请参考以下文章