程序,线程,线程池
进程是资源分配最小单位,线程是程序执行的最小单位。计算机在执行程序时,会为程序创建相应的进程,进行资源分配时,是以进程为单位进行相应的分配,每个进程都有相应的线程,在执行程序是,实际上是执行相应的一系列线程。
线程:程序执行流的最小执行单位,是行程中实际运作单位,经常容易和进程这个概念混淆
简单来说,一个应用程序的运行就可以被看做是一个进程。是运行中实际的执行任务者,可以说,进程中包含了多个可以同时运行的线程。
线程的生命周期
-
新建线程:new 当一个线程对象被创建时,它处于新建状态,此时线程对象已经被创建,但是没有开始运行。
-
就绪状态:Runnable 当线程调用start()方法后,线程进入就绪状态,此时线程已经准备好状态,此时线程正在执行任务。
-
运行状态:当就绪状态的线程获得CPU时间并开始执行时,线程进入运行状态,此时线程正在执行任务。
-
阻塞状态:当线程因为某些原因无法继续执行时,线程进去阻塞状态,阻塞状态可以分为等待I/O,等待锁,等待信号等。
-
等待状态:Waiting 当线程需要等待某些条件满足时,线程进入等待状态,等待状态可以通过wait() fangfa ,join()方法等实现
-
终止状态:当线程完成了任务或者异常等原因退出时,线程进入终止状态,此时线程的声明周期结束。
创建线程的方式:
- 继承Thread类:通过继承Thread类并重写其run方法,run方法中包含了线程需要执行的任务。创建Thread类的实例,并通过调用该实例的start()方法来启动线程
class MyThread extends Thread{
@Override
public void run() {
System.out.println("创建线程的第一种方法--继承Thread,重写run方法");
}
}
public class Test1 {
public static void main(String[] args) {
Thread t = new MyThread();
t.start();
System.out.println("main线程执行完毕!!!");
}
}
运行结果如下:
实现Runable接口,重写run()方法.
class MyThread2 implements Runnable{
@Override
public void run() {
System.out.println("实现线程的第二种方式,实现Runable接口,重写run方法");
}
}
public class Test2 {
public static void main(String[] args) {
Runnable runnable = new MyThread2();
Thread t = new Thread(runnable);
t.start();
System.out.println("main线程执行完毕!!!");
}
}
使用匿名内部类(本质上是使用继承Thread类).
public class Test3 {
public static void main(String[] args) {
Thread t = new Thread(){
@Override
public void run() {
System.out.println("实现多线程的第三种方式,继承Thread重写run方法,使用匿名内部类!!");
}
};
t.start();
System.out.println("main线程执行完毕!!!");
}
}
使用匿名内部类(本质上是实现了Ranable接口).
public class Test4 {
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("创建线程的第四种方式,实现Runable接口,重写run方法,使用匿名内部类");
}
});
t.start();
System.out.println("main线程执行完毕!!");
}
}
(更推荐更常用) 使用lambda表达式.
public class Test5 {
public static void main(String[] args) {
Thread t = new Thread(()->{
System.out.println("创建线程的第五种方法,使用lambda表达式");
});
t.start();
System.out.println("main线程执行完毕!!!");
}
}