进程的概念
是操作系统(OS)中并发执行(同时执行)的程序任务
进程的特点
-
宏观并行,微观串行
-
原理:在一个时间段内,CPU会将时间段划分成若干个时间片,只有拥有时间片的程序才能执行自身内容,时间片之间交替执行,当时间片的划分足够细小,交替频率足够快,就会形成并行的假象,但是本质上仍然是串行
线程的概念
是进程的基本组成部分,是进程中并发执行的程序任务
线程的特点
-
宏观并行,微观串行
-
原理:一个时间片只能被一个进程拥有,一个进程在一个时间片内只能执行一个线程,进程之间交替执行,所以线程也是串行
多线程
-
只存在多线程,不存在多进程
-
只有正在执行中的程序才能称为进程,一个时间片只能被一个进程拥有,所以不存在多进程
-
只要开启了程序任务,无论是否在执行,都被称为线程,所以存在多线程
线程的组成
-
时间片
-
OS调度分配
-
-
代码
-
栈:独立
-
堆:共享
-
-
数据
线程的创建
-
创建线程对象时必须指明其需要完成线程任务
-
继承Thread类,重写run方法
class MyThread extends Thread{ /** * 当前线程需要执行的任务内容 */ @Override public void run() { //循环输出1-100 for (int i = 1; i <=100 ; i++) { System.out.println(i); } } } public class Test { public static void main(String[] args) { //创建线程对象 Thread t1 = new MyThread(); Thread t2 = new MyThread(); /*t1.run(); t2.run();*/ //开启线程 t1.start(); t2.start(); } }
-
实现Runnable接口,重写run方法,在Thread构造内传入该实现类对象
/** * 实现类-线程任务 */ class MyRunnable implements Runnable{ @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(i); } } } public class TestRunnable { public static void main(String[] args) { //创建线程对象,传入线程任务 Thread t1 = new Thread(new MyRunnable()); Thread t2 = new Thread(new MyRunnable()); //开启线程 t1.start(); t2.start(); } }
//使用匿名内部类创建线程对象 Thread t1=new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("t1::"+i); } } }); //利用lambda创建一个Thread对象 Thread t2=new Thread(()->{ for (int i = 100; i <200 ; i++) { System.out.println(i); } });
更推荐使用第二种创建方式:更符合类的单一职责
使用
-
开启线程需要调用start方法,run方法的调用并不会在JVM进程中开启新的线程
-
执行:当开启多个线程之后,线程之间会开始争夺时间片,只有抢到时间片的线程才能执行自身run方法内容,如果在执行过程中丢失时间片,会暂停run方法的执行,直至下次拿到时间片
-
主函数也称为主线程,其必定是第一个拿到时间片的线程,当开启多个线程之后,JVM进程执行结束的标志不再是主函数结束,而是所有线程执行结束