进程与线程
什么是进程
进程是程序的一次执行过程,是一个动态的概念,是程序在执行过程中分配和管理资源的基本单位,每一个进程都有一个自己的地址空间,也就是说,进程是应用程序运行的状态,应用程序的执行实例,有独立的内存空间和系统资源
什么是线程
一个进程中包括多个线程,线程是 CPU 调度和分派的基本单位,是进程中执行运算的最小单位,真正在 CPU 上运行的是线程,可以与同一个进程中的其他线程共享进程的全部资源
线程的生命周期
线程是进程的一部分,它也是一个动态执行的概念,有从产生到死亡的过程,线程的生命周期可以分为五个部分:
新生状态->(线程创建了,还未运行)->可运行状态(CPU 准备调度线程)->(系统调度,获取 CPU 资源)->运行状态->阻塞状态(线程阻塞,让出 CPU 资源)->死亡状态
新生状态
线程对象被创建后,这个线程就处于新生状态,这个状态会一直持续到 start() 这个线程
可运行状态
当线程调用了 start() 方法后,该线程就进入可运行状态,进入可运行状态的线程会被插入就绪队列中,等待 JVM 里线程调度器的调度
运行状态
当可运行状态的线程得到 CPU 资源后,该线程就可以执行 run(),此时线程便处于运行状态,运行状态的线程可以向阻塞状态、就绪状态和死亡状态转变
阻塞状态
当一个线程调用了 sleep()、join()、yield() 等方法,失去所占用的资源后,线程进入阻塞状态,在说的资源或者睡眠时间已到后可以重新进入就绪状态
死亡状态
正常死亡和非正常死亡都会杀死进程,进程死亡即进程被销毁
线程的优先级
在 Java 中,线程有优先级的概念,其范围为 1 - 10,默认优先级为 5,但是优先级是概率性的,优先级高的线程并不一定优先执行,只是被分配资源的概率更高
setPriority() 方法有三种常量:
MAX_PRIORITY (10)
MIN_PRIORITY (1)
NORM_PRIORITY (5)
Thread t = new Thread(mt);
t.setPriority(1);
t.start();
Thread t2 = new Thread(mt);
//设置线程名称
t2.setName("sc");
//设置线程优先级,但是是概率事件,并非优先级高一定先运行,1 - 10 表示,10 最高,默认值是 5
t2.setPriority(Thread.MAX_PRIORITY);
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
线程在 Java 中的两种创建方式
在 Java 中有两种创建线程的方法,下面逐个解释并说明他们的区别
继承 Thread 类
通过继承 Thread 类来创建线程,创建该类的实例,继承类必须重写 run() 方法,run() 方法中是线程所执行的代码
public class ThreadTest1 {
public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start();
MyThread mt2 = new MyThread();
mt2.start();
}
}
class MyThread extends Thread {
int count = 10;
@Override
public void run() {
while (count > 0) {
count--;
System.out.println(Thread.currentThread().getName() + " " + count);
}
}
}
Thread 类实际上是实现了 Runnable 接口的实例
class Thread implements Runnable
通过实现 Runnable 接口
实现 Runnable 接口直需要重写其中的 run() 方法,Thread 的构造方法中,可以通过静态代理的方法,使用 Runnable 的实现类来创建进程
public class ThreadTest2 {
public static void main(String[] args) {
MyThread2 mt = new MyThread2();
//静态代理
Thread t = new Thread(mt);
t.setPriority(1);
t.start();
Thread t2 = new Thread(mt);
t2.start();
}
}
class MyThread2 implements Runnable {
int count = 10;
@Override
public void run() {
while (count > 0) {
count--;
System.out.println(Thread.currentThread().getName() + " " + count);
}
}
}
区别
首先,单继承不能再继承其他类,而实现可以多实现,同时也可以继承
另外,通过实现 Runnable 接口来创建的线程可以共享实现类的资源,这是多线程实现的基础