一、线程与进程的区别
1、进程是程序的一次执行过程,是程序运行的基本单位
2、进程是比线程更小的执行单位,一个进程可以产生多个线程,多个线程共享进程的堆和方法区,每个线程都有自己独立的栈和程序计数器,因此线程之间切换的开销比进程切换小

二、并发与并行
并发:同一时间段内,多个线程交替执行
并行:同一时刻多个线程同时执行
三、同步与异步
- 同步:发出一个调用之后,在没有得到结果之前, 该调用就不可以返回,一直等待。
- 异步:调用在发出之后,不用等待返回结果,该调用直接返回
四、线程的生命周期和状态(6个)
- NEW: 初始状态,线程被创建出来但没有被调用
start()。 - RUNNABLE: 运行状态,线程被调用了
start()等待运行的状态。 - BLOCKED:阻塞状态,需要等待锁释放。
- WAITING:等待状态,表示该线程需要等待其他线程做出一些特定动作(通知或中断)。
- TIME_WAITING:超时等待状态,可以在指定的时间后自行返回而不是像 WAITING 那样一直等待。
- TERMINATED:终止状态,表示该线程已经运行完毕。

sleep与wait对比:
-
sleep()方法没有释放锁,而wait()方法释放了锁 。wait()通常被用于线程间交互/通信,sleep()通常被用于暂停执行。wait()方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象上的notify()或者notifyAll()方法。sleep()方法执行完成后,线程会自动苏醒,或者也可以使用wait(long timeout)超时后线程会自动苏醒。sleep()是Thread类的静态本地方法,wait()则是Object类的本地方法。
五、进程的生命周期和状态
-
新建状态(New):该状态表示进程已经被创建,但尚未开始执行或分配资源。
-
就绪状态(Ready):该状态表示进程已经被分配了所有必要的资源,并已经准备好在处理器上运行,只等待处理器的调度。
-
运行状态(Running):该状态表示进程当前正在处理器上执行指令。
-
阻塞状态(Blocked):该状态表示进程暂时无法运行,因为它正在等待某些事件的发生,例如 I/O 操作或者信号量等。
-
终止状态(Terminated):该状态表示进程已经完成了它的任务,并且被操作系统回收了所有占用的资源。
六、线程死锁
多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。
1、四个必要条件
- 互斥条件:该资源任意一个时刻只由一个线程占用。
- 占有并等待条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放。
- 不可抢占条件:线程已获得的资源在未使用完之前不能被其他线程强行剥夺,只有自己使用完毕后才释放资源。
- 循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系
2、如何预防和避免死锁
1、预防死锁
- 破坏请求与保持条件:一次性申请所有的资源。
- 破坏不剥夺条件:占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源。
- 破坏循环等待条件:靠按序申请资源来预防。按某一顺序申请资源,释放资源则反序释放。破坏循环等待条件。
2、避免死锁
分配资源前用银行家算法进行探测,如假设分配资源后系统仍处于安全状态则进行分配
3、检测死锁
使用进程-资源分配图判断是否存在死锁
4、解除死锁
写一个死锁,代码如下:
public class DeadLockDemo {
private static Object resource1 = new Object();//资源 1
private static Object resource2 = new Object();//资源 2
public static void main(String[] args) {
new Thread(() -> {
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource2");
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
}
}
}, "线程 1").start();
new Thread(() -> {
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource1");
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
}
}
}, "线程 2").start();
}
}