1.Volatile解决了多线程可见性问题和重排序问题。
2.可见性问题:jmm内存模型,当主线程的本地内存修改后,会及时更新到主内存中,其他的子线会在主内存及时更新
3.重排序:单线程环境下,不考虑重排序问题,多线程环境下,重排序会导致线程安全问题。
4.当需要停止一个线程时,thread自身的.stop方法已经过时,在执行stop方法时,如果停止主线程,子线程也无法执行;可以采用while循环去处理,将子线程放在while循环中,循环条件默认为flag=true,当子线程执行完毕后,将flag设置为false,退出循环。
5.原子性问题解决方案:首先,volatile不能解决原子性问题,被访问的资源必须是static静态的共享资源,否则不能被多个线程调用,解决原子性的可以通过悲观锁如synchronized在方法上加锁实现原子性,也可以用过乐观锁 version版本号去解决,也可以通过atomicInteger原子类去解决原子性问题。
6.并发队列:分为阻塞队列和非阻塞队列。
7.阻塞队列常用的是:数组和链表的阻塞队列,底层是带lock锁的,确保并发线程的安全问题。
8.非阻塞队列的是,concurrentLinkedQuene 用.offer去实现队列的先进先出方式;如果入队的时候队列满了,我们就指定等待时间,进入阻塞状态。
9.为什么使用线程池:
每次创建线程的时候,我们都要去new Thread().start(),造成资源消耗,也不利于管理。所以我们通过创建线程池的ThreadPoolExcutor核心类去实现线程池,以应对多线程并发环境
10.线程池底层原理:
当我们提交任务时,会先将线程数量和核心线程数量进行比较,如果线程数量小,那么就会创建一个新的线程来执行任务。执行后,线程不会关闭,会从阻塞队列里去拿新的任务执行,重复以上操作。如果阻塞队列里没有新的任务,就会等新的任务进来后,再次提交,知道线程数量等于核心线程数量时,如果再提交任务,就会把新的任务放在其他队列里,直到核心线程池执行完其他任务时,再执行其他队列的任务。
11.线程池的核心参数:
核心线程的大小,最大线程的大小,空闲线程存活时间,消亡时间单位,等待执行的线程的工作队列,创建线程的工厂
12.线上突然宕机怎么处理
在提交任务的时候,在数据库存储提交任务的状态,未提交,已提交,已完成。待系统重启后,读取数据库状态为未完成的线程,在重新提交到线程池中。