什么是上下文切换?
巧妙地利用了时间片轮转的方式, CPU 给每个任务都服务一定的时间,然后把当前任务的状态保存下来,在加载下一任务的状态后,继续服务下一任务,任务的状态保存及再加载, 这段过程就叫做上下文切换。时间片轮转的方式使多个任务在同一颗 CPU 上执行变成了可能。
上下文:指某一时间点 CPU 寄存器和程序计数器的内容
几种发生上下文切换的情况:
主动让出 CPU,比如调用了 sleep(), wait() 等。
时间片用完,因为操作系统要防止一个线程或者进程长时间占用CPU导致其他线程或者进程饿死。
调用了阻塞类型的系统中断,比如请求 IO,线程被阻塞,被终止或结束运行
线程之间如何进行通信
通过共享内存或基于网络通信
如果是基于共享内存进行通信,则需要考虑并发问题,什么时候阻塞,什么时候唤醒
想Java中的wait()、notify()就是阻塞唤醒
通过网络就比较简单,通过网络连接将数据发送给对方,当然也要考虑到并发问题,处理方式就是加锁等方式。
说一下ThreadLocal
ThreadLocal是Java中所提供的线程本地存储机制,可以利用该机制将数据缓存在某个线程内部,该线程可以在任意时刻、任意方法中获取缓存的数据。
ThreadLocal底层是通过 TreadLocalMap来实现的,每个Thread对象中都存在一个 ThreadLocalMap,Map的key为 ThreadLocal对象,Map的 value为需要缓存的值 。
ThreadLocalMap由一个个 Entry对象构成 Entry继承自 WeakReference< Threadlocal<?>>,一个 Entry由 Threadlocal对象和 object构成,由此可见,Entry的key是 Threadlocal对象,并且是一个弱引用。当没指向key的强引用后,该key就会被垃圾收集器回收
当执行set方法时, Threadlocal首先会获取当前线程对象,然后获取当前线程的 ThreadLocalMap对象。再以当前 Threadlocal对象为key,将值存储进 Threadlocalmap对象中
get方法执行过程类似,Threadloca首先会获取当前线程对象,然后获取当前线程的 ThreadLocalMap对象。再以当前 ThreadLocal对象为key,获取对应的value
由于每条线程均含有各自私有的 ThreadLocalMap容器,这些容器相互独立互不影响,因此不会存在线程安全性问题,从而也无需使用同步机制来保证多条线程访问容器的互斥性。
使用场景:
在进行对象跨层传递的时候,使用ThreadLocal可以避免多次传递,打破层次间的约束
线程间数据隔离
进行事务操作,用于存储线程事务信息
数据库连接,Session会话管理
Spring框架在事务开始时会给当前线程绑定一个 Jdbc Connection,在整个事务过程都是使用该线程定的
connection来执行数据库操作,实现了事务的隔离性, spring框架里面就是用的 Threadlocal来实现这种隔离。