一、进程与线程概念
进程指的就是一个正在运行的应用程序,打开一个应用程序也就开启了一个进程。线程指的就是应用程序下一个执行任务。一个进程包含一个或多个线程,进程只负责资源的调度和分配,而线程才是真正的执行单元。
二、单线程与多线程
单线程:多个任务按顺序执行,一个任务执行完成,另一个任务才能开始执行。
多线程:单核cpu下效率不一定比单线程高。例如:当重复执行一些计算任务时,使用多线程也只是多个线程交替执行,与单线程无异,且创建和销毁多个线程需要花费比单线程更多的时间。但是如果任务中含有I/O操作时,使用多线程效率比单线程高,当某个线程去执行I/O操作不占用cpu资源时,其他线程此时可以占用cpu,最大限度提升了cpu利用率。多核cpu下效率一定比单线程高,多个任务可以并行执行,无需等待前面的线程执行完成。
三、多线程五种状态
1.新生状态:线程被创建时,处于新生状态。
2.就绪状态:调用start()方法启动线程时,处于就绪状态,处于就绪状态并不一定立即执行run()方法,还需要与其他线程竞争cpu资源,抢到cpu时间片才能运行线程。
3.运行状态:抢夺到cpu时间片,执行run()方法中的业务逻辑,才代表当前线程处于运行状态。
4.阻塞状态:线程运行过程中可能由于各种原因而进入阻塞状态。阻塞状态的线程只是暂时让出cpu资源,其他就绪状态的线程可以争夺时间片执行。
5.死亡状态:run()方法正常结束或方法内抛出异常。
四、创建线程的三种方式
1.继承Thread类,重写run()方法
public class ThreadDemo01 extends Thread{
@Override
public void run() {
//此处写需要该线程处理的业务逻辑
}
public static void main(String[] args) {
//启动线程
//new ThreadDemo01().start();
ThreadDemo01 threadDemo01 = new ThreadDemo01();
}
}
2.实现Runnable接口,实现run()方法
public class ThreadDemo02 implements Runnable {
@Override
public void run() {
//此处写需要该线程处理的业务逻辑
}
public static void main(String[] args) {
//启动线程
Thread thread = new Thread(new ThreadDemo02());
System.out.println(thread.getName());
}
}
3.通过匿名内部类创建线程
public class ThreadDemo03 {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
//此处写需要该线程处理的业务逻辑
}
});
//启动线程
thread.start();
System.out.println(thread.getName());
}
}