目录
线程
什么是进程、线程?
进程是程序运行的一次执行过程,是系统程序运行的基本单位。
线程是比进程还小的执行单位,一个进程有多个线程。与进程不同的是同类线程具有相同的和方法区资源,但是每个线程都有自己的方法区栈、程序计算器、虚拟机栈。
多线程(线程和进程的关系 为什么使用多线程)
1.线程属于进程,一个进程可以拥有多个线程
2.进程有独立空间,线程无,上下文切换中,进程时间久、耗费资源大,线程的并发性高,进程的并发性低,不同的进程有不同的内存空间,而所有的线程只有一个内存空间。
多线程优点:1.减少程序响应时间;2.提高CPU利用率;3.数据共享率高;4.简化程序结构
保证线程安全
多个线程同时操作共享资源时,就会出现线程安全。
1.原子类:遵循CAS规则,比较要更新的值是否等于期望值,如果是则更新,如果不是则失败。
2.volatile关键字:在多处理器开发保证了共享变量的“可见性”,从而可以保证单个变量读写时的线程安全;
3、synchronized+juc包下的lock锁。
死锁定义以及发生条件、破坏?
定义:两个或者两个以上进程互相竞争资源而造成持续等待的情况。
互斥条件:一个资源只能被一个线程使用;
请求和保持条件:一个线程在阻塞等待某个资源,不释放已占有资源;
不剥夺条件:一个线程已经在获得资源的情况,在未使用完前,不得剥夺。
环路等待条件:若干线程之间形成一种头尾相接的循环等待资源关系。
1.破坏请求与保持条件:一次性申请所有资源
2.破坏不剥夺条件:占用部分资源的线程进一步申请其他资源,若申请不到,可以主动释放占用的资源。
3.破坏循环等待条件:靠顺序来申请资源预防。在释放资源的时候逆向释放。
如何禁止指令重排序
运用volatile关键字,将变量申明为volatile,对这个变量进行读存操作,会有内存屏障来禁止指令重排序。
进程的通讯方式
管道、命名管道、信号、消息队列、共享内存、内存映射、信号量、socket
乐观锁和悲观锁(乐观锁怎么实现)
乐观锁:假设情况都是最好的,认为共享资源被访问时都不会出现问题,所以每一次共享资源被访问都不会添加锁,线程可以不停执行,直到提交修改需要去验证资源是否被其他线程进行了修改。
线程在对数据进行修改时,会先核验版本号是否一致,一致则修改,不一致则不修改。
悲观锁:假设情况都是最坏的,认为共享资源被访问时都会出现问题,所以每一次共享资源被访问都会添加锁,这样下一个线程想要访问资源时需要上一个线程释放资源。缺点:死锁
线程在对数据进行修改时,其他线程无法进入。
乐观锁通常有CAS实现。
CAS:用一个预期值和将更新的变量进行对比,若相等则进行下一步更新。
问题:ABA问题、循环时间开销过大、只能保证一个共享变量的操作。
线程安全的集合
JUC 下有Vector、HashTable,ConcurrentHashMap,Collections 中synchronized将非线程安全集合包装成线程安全类。
线程状态
创建、就绪、运行、阻塞、终止。
AQS
AQS成为抽象队列同步器。核心思想:当一个线程申请共享资源时,共享资源是处于空闲状态,则将当前的线程设置为有效的工作线程。若共享资源被占用,则需要一套线程阻塞等待以及被唤醒锁分配的机制,机制为AQS,由CLH锁实现的。
Threadlocal
线程变量,将需要并发访问的资源复制多份,让每个线程拥有一份资源,由于每个线程都拥有自己的资源副本,从而没必要对该变量进行同步。