一、进程与线程的定义
进程:正在内存中执行的应用程序。
线程:是进程的一个执行单元。负责进程中程序的执行。一个进程中允许有多条线程,称之为多线程,如果只有一条线程,称之为单线程。一个进程至少必须有一条线程。
二、多线程的认识
【线程认识误区】
多线程并没有真正提高运行速度,在同一时刻只有一条线程在执行,只是因为线程切换的太快,产生同时执行的假象。所以尽管叫做多线程,但某一时刻仍然是单线程在工作。
【Java中的线程方式】
抢占式调度:线程具有优先级。理论上会先执行优先级高的线程。如果线程的优先级相同,那么会随机执行一条线程(线程的随机性)。对于CPU的一个核而言,同时只能有一条线程在执行。但是线程在核上进行着高速切换,所以感觉是同时在执行。
【线程的优点】
1.提高用户的体验。
2.提高了CPU的利用率。
线程的执行需要和计算机硬件交互。当线程和计算机硬件交互时,CPU会暂时的空置。所以多线程就能够提高CPU的利用率。
一条线程不会占据整个cpu的资源。
三、多线程的实现
【方式一】继承Thread类
步骤:
- 定义一个类继承自Thread
- 在子类中重写run方法,将需要被新线程执行的代码放入run方法
- 创建子类对象,调用start方法开启线程。
public class ThreadDemo {
public static void main(String[] args) {
SubThread sub = new SubThread();
//调用start方法,开启线程
sub.start();
for (int i = 0; i < 100; i++) {
System.out.println("主方法线程执行 "+ i + " 次");
}
}
}
/**
* 自定义线程测试,继承Thread类
*/
class SubThread extends Thread{
//重写run方法
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("自定义线程执行 "+ i + " 次");
}
}
}
【方式二】实现Runnable接口
步骤:
- 定义类实现Runnable接口
- 实现接口中的run方法
- 创建实现类的对象
- 创建Thread对象,并且将实现类对象通过Thread的构造方法传入
- 调用start方法,开启新的线程
public class RunnableDemo {
public static void main(String[] args) {
//创建Thread对象,并将实现Runnable接口的类传入到Thread对象中
Thread t = new Thread(new SubRun());
t.start();
for (int i = 0; i < 100; i++) {
System.out.println("主方法线程执行 "+ i + " 次");
}
}
}
/**
定义类实现Runnable接口
实现接口中的run方法
*/
class SubRun implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("自定义线程执行 "+ i + " 次");
}
}
}
补充:
【1】线程中run方法和start方法的区别?
run:并没有真正的开启新的线程,只是在原来线程中存放执行方法的代码
start:开启新的线程去执行run方法中的代码。
【2】线程的运行结果是不唯一的,谁先抢到资源,谁先运行