区别:
1、进程中包含线程,每一个进程都至少一个线程(主线程)
2、进程是申请系统资源的最小单位
3、进程是CPU调度的最小单位
4、线程之间共享进程申请的系统资源
5、一个线程崩溃了会影响整个进程
进程的组织方式:
通过一个双向链表组织PCB:
创建一个进程就是把PCB加入到链表中;
销毁一个进程就是把PCB从链表中删除;
查看所有的进程就是遍历双向链表。
线程概念及优势:
多进程能充分利用CPU资源去处理复杂业务,从而提高效率。
但是进程申请资源对系统的性能影响较大,涉及内存和文件资源,处理一个事情有一份资源就够了。
线程用的就是进程启动时从操作系统中分配的资源,(线程也可以叫轻量级的进程),当创建一个进程时,进程中就会包含一个线程,叫主线程。
我们可以理解为进程就是一个公司,线程就是员工,一个公司可以有多个员工,一个进程可以创建多个线程。
优势:
创建速度比进程快;
销毁速度比进程快;
线程的CPU调度速度比进程快。
线程的创建:
创建线程的个数,根据CPU逻辑处理器数量来作为参考。
通过多线程的方式可以提高效率,但当线程数量大于逻辑处理器数时,由于过多线程处于阻塞等待状态,不能真正发挥作用,反而因创建线程消耗系统资源。
当某一个线程出现问题,会影响其他线程,进而影响整个进程。
一个线程崩溃会导致整个进程崩溃。
线程的创建方式:
在JAVA中Thread类用来描述一个线程,创建的每个线程都是Thread类的对象
1、继承Thread类(线程对象),重写run()方法(线程要执行的具体任务)
2、实现Runnable接口,重写run()方法
更推荐第二种
简化的方式:
通过匿名内部类的方式,创建Thread的子类,Runnable的子类
通过Lambda表达式的方式
多线程的优势:
能够增加运行速度。
通俗讲,
一个大的任务来分配给多个执行者来一起执行就会更快完成任务,进而提高效率;
设置一个场景,执行两次自增到10亿的操作,
单线程,串行执行任务;
多线程,这里设置两个线程,两个线程分别执行;
public class Demo {//大数可以使用分隔符_private static long count = 10_0000_0000l;public static void main(String[] args) {//串行serial();//并行concurrency();}private static void concurrency(){//记录开始时间long begin = System.currentTimeMillis();//创建两个线程,各自累加Thread t1 = new Thread(()->{long a = 0l;for(int i = 0; i < count; i++){a++;}});t1.start();//启动线程Thread t2 = new Thread(()->{long b = 0l;for(int i = 0; i < count; i++){b++;}});t2.start();//启动线程long end = System.currentTimeMillis();System.out.println("并行执行时间:"+ (end - begin));}private static void serial(){//记录开始时间long begin = System.currentTimeMillis();long a = 0l;for(int i = 0; i < count; i++){a++;}long b = 0l;for(int i = 0; i < count; i++){b++;}//记录结束时间long end = System.currentTimeMillis();System.out.println("串行执行时间:" + (end - begin));}
}
结果:
我们可以看到并行执行时间快很多,但是这并不是真的并行执行时间,
开始记录时间后创建了线程t1,然后开启t1,接着创建线程t2并开启该线程,然后就打印了执行时间,但此时两个线程还在执行任务,没有结束。
要想打印出真正的并行执行时间,可以让线程调用join()方法,哪个线程调用join方法,主线程就要等待该线程执行完它的任务
所以我们能够看出通过多线程的方式能够提高效率,并行的执行时间是串行的一半多一点,之所以多一点是由于创建线程还会耗时。
但并不是多线程的效率都比单线程高,当任务量很少时,由于多线程创建会耗时,单线程效率可能更高。
当把10亿换成5万后可以看到串行执行时间更短,效率更高