一.相关概念
①程序: 为完成某一任意, 用某种语言编写的一组指令的集合. 简单说就是"代码"
②进程: 运行中的程序. 程序的一次执行过程, 或是正在运行的一个程序. 是一个动态过程, 具有开始, 存在, 结束的过程
③线程:线程由进程创建, 是进程的一个实体, 一个进程可以拥有多个线程. 举例: 打开QQ音乐(进程), 下载歌曲, 可以同时下载多个歌曲(线程)
a.单线程: 同一时刻, 只能有一个线程执行
b.多线程: 同一时刻, 可以执行多个线程. 例如: QQ可以打开多个聊天窗口
④并发: 同一时刻, 多个任务"交替执行", 因为执行速度极快, 所以会有一种同时进行的"错觉", 单核CPU可以实现并发, 无法实现并行
⑤并行: 同一时刻, 多个任务"同时进行", 多核CPU可以实现并行, 也可以实现并发
二.启动线程
①两种方法:
a.继承 Thread类 重写 run() 方法, 通过调用 start()方法启动线程
b.实现 Runnable接口, 重写 run() 方法, 创建 Thread 实例对象, 调用 Thread类中的 start()方法启动线程
②代码演示:
方法a启动线程代码演示:
public class CreatThread extends Thread {
public static void main(String[] args) {
// 创建线程对象, 创建完成后启用方法并不会立刻启动线程, 底层由操作系统启动线程, java做不到启动线程
CreatThread creatThread = new CreatThread();// 创建实例对象
creatThread.start();// 启动线程
for (int i = 0; i < 5; i++) {
System.out.println("主线程: abcd");
try {
Thread.sleep(1000);// 休眠一秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("线程1: ABCD");
try {
Thread.sleep(1000);// 休眠一秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行结果:
方法b启动线程代码演示:
public class CreatThread2 implements Runnable {
public static void main(String[] args) {
CreatThread2 creatThread2 = new CreatThread2();
Thread thread = new Thread(creatThread2, "第二线程");// 第二个参数传入字符串, 自定义线程名称
thread.start();
for (int i = 0; i < 5; i++) {
System.out.println("主线程: abcd");
try {
Thread.sleep(1000);// 休眠一秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("第二线程: ABCD");
try {
Thread.sleep(1000);// 休眠一秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行结果:
由运行结果可以看出来, 主线程和start()创建的线程二者同时执行. 不管使用哪一种创建线程的方式, 启动线程调用的都是start()方法, 而不是run()方法, 如果只是单纯的调用run()方法, 则只是在主线程中调用了该方法, 并没有启动线程
③继承Thread和实习Runnable接口的区别
a.本质二者并没有区别, Thread类 实现了Runnable接口
b.实现了Runnable接口的方式创建线程可以多个线程共享一个资源, 并且由于Java是单继承机制, 如果要创建线程的类继承了别的类, 这个类就无法继承Thread类. 所以建议使用实现Runnable接口的方式创建线程
通过debug追源码, 查看start()的操作流程, 会发现真正创建一个线程的是start0(), 该方法是一个本地方法, 由操作系统启动线程, java没有能力启动线程