进程
进程就是用来加载指令、管理内存、管理IO的
操作系统以进程为单位,分配系统资源(CPU时间片、内存等资源),进程是资源分配的最小单位
线程
有时被称为轻量级进程,是操作系统(CPU调度)执行的最小单位
进程间通信的方式
管道
信号
消息队列
共享内存
套接字
线程的同步互斥
同步:一个线程的执行依赖另一个线程的消息,如果没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒
互斥:对于共享系统资源,单个线程访问的排他性
上下文切换
上下文切换需要保存现场和还原线程,需要消耗5-10ms的时间
内核模式和用户模式
系统调用,异常事件,设备中断都会导致用户和内核模式的切换。CAS操作并没有涉及到用户态到内核态的切换,它只是cpu在执行指令并没有涉及到系统调用
线程的生命周期操作系统层面分为5种状态,分别是:初始状态,可运行状态,运行状态,休眠状态和终止状态
初始:创建初始化;可运行:调用start()方法,但是没有获得cpu时间片;运行状态:获得CPU时间片开始执行;终止:线程执行完成进行回收;休眠:等待唤醒
java线程分为6种,查看Thread的State枚举类:NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED
测试线程的blocked以及其他状态
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
synchronized (lock) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(() -> {
synchronized (lock) {
System.out.println("执行t2");
}
});
System.out.println("t1: " + t1.getState()); //NEW
t1.start();
System.out.println("t1: " + t1.getState()); //RUNNANLE
Thread.sleep(100); //确保t1获得锁
t2.start();
System.out.println("t1: " + t1.getState()); //TIME_WAITING
Thread.sleep(1000);
System.out.println("t2: " + t2.getState()); //t2没有获得锁其状态为BLOCKED
}
如果t1中调用lock.wait()而t2中调用lock.notifyAll(),t1在释放锁以后会变成WAITING状态,当t2获得锁以后调用lock.notifyAll(),t1又会变成RUNNABLE状态,最后所有线程执行完了,都会变为TERMINATED状态
创建线程的方式
1、使用Thread类或者继承Thread类
2、实现Runnable配合Thread
3、使用有返回值的Callable,他是借助线程池的
4、使用lambda表达式
本质上都是通过new Thread()创建线程,并通过start方法调用run()
优雅的停止线程
stop():释放对象锁,直接终止线程---不推荐
中断机制来停止线程,它可以让线程执行完任务后停止线程
Thread t = new Thread(() -> {
int count = 0;
while (true) {
count++;
//不会清除中断标志位
boolean interrupted = Thread.currentThread().isInterrupted();
//清除中断标志位
// boolean interrupted = Thread.interrupted();
System.out.println(count);
if (interrupted) {
System.out.println("进入中断");
}
if (count == 10) {
break;
}
}
});
t.start();
t.interrupt();
线程之间的通信
volatile、wait/notify(依赖monitor)、LockSupport#park()/unpark(),管道输入输出流,Thread.join()
个人笔记



