一、进程与线程的区别:
进程:是系统进行分配和管理资源的最基本单位
我们在系统上去运行一个程序的时候,cpu就会为程序对应的资源分配相应的资源。
比如说:我们运行程序肯定需要内存,相应的磁盘空间,IO设备等等的资源,都是由系统进行相应的分配的,分配都是以进程为最基本的单位。
线程:进程的一个执行单元,是进程内调度的实体,是CPU调度和分派的基本单位,是比进程更小的独立运行的基本单位。线程也被称为轻量级进程,线程是程序执行的最小单位。
总结:一个程序至少有一个进程(可以开启两个相同的应用),一个进程至少有一个线程(main方法)。下面的图是证明一个进程至少有一个线程。
为什么一个系统进行分配和管理资源的时候是以进程为基本单位呢?比如一个系统相当于是一个公司,一个公司里面有好几百人,如果一个人去管理好几百人是忙不过来的,可能每天去下公司看下每个人手头上工作完成的情况,这个时候你也差不多快下班了。明智的选择是把这些人划分成一个一个的组,去下达任务的时候,由组长去执行统计员工完成的情况。进程会有自己独立的地址的空间。每启动一个进程,系统就会为它分配地址空间,去建立相应的数据表来维护代码段,数据段。这些的操作都比较是昂贵的,比较耗资源的操作。如果线程共享进程中的数据的,它使用相同的地址空间,因此 cpu切换线程 的时候所花费的时间比进程要小的多。同理创建一个线程的开销也是比创建一个进程的开销要小的。
线程之间的通信更方便,同一进程下的线程共享全局变量,静态变量等数据,而进程之间需要以通信的方式进行。如何处理好同步和互斥也是编写多线程程序的难点。
多线程程序更健壮,进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其他进程产生影响,而线程知识一个进程中的不同执行路径。线程有自己的堆和栈和局部变量,但 线程之间没有单独的地址空间,所以可能出现一个线程出现问题时,进而导致整个程序出现问题。
二、看下线程的状态:
New,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED,总共有六种状态
所以说线程有6种状态
首先看下:
初始(NEW):新创建一个线程对象,但还没有调用start()方法
运行(Runnable):处于可运行状态的线程正在JVM种执行,但它可能正在等待来自操作系统的其他资源,例如处理器。调用start方法会进入runnable状态,cpu为每一个线程分配相应的时间片,有可能时间片还没有分配到这个线程的时候,虽然它处于runnable状态,但是还没有去真正的执行run方法
代码如下:
Thread thread = new Thread(()->{
try {
//让线程不会那么快的退出
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
});
thread.start();
阻塞(BLOCKED):线程阻塞于synchronized锁,等待获取synchronized锁的状态
Object obj=new Object();
Thread thread = new Thread(()-> {
synchronized (obj) {
try {
Thread.sleep(100000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
Thread.sleep(2000L);
Thread thread1 = new Thread(()-> {
synchronized (obj) {
}
});
thread1.start();
等待(WAITING):Object.wait(),join(),LockSupport.park(),进入该状态的线程需要等待其他线程做出一些特定动作(通知:唤醒或中断),其他的线程才会退出。
Object obj=new Object();
Thread thread = new Thread(()-> {
synchronized (obj) {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
超时等待(TIME_WATING):Object.wait(long):超时了这个时间可以自动的返回,Thread.join(),LockSupport.parkNanos(),LockSupport.parkUntil,该状态不同于WAITING:它可以在指定的时间内自动返回
终止(TERMINATED):表示该线程已经执行完毕。
初始和终止的状态看不到,其他的状态可以通过相应的代码能看的到相应的状态。