一:JMM(Java内存模型)
![](https://i-blog.csdnimg.cn/blog_migrate/7f5df053096c4e40982c7abc8dd95f8a.png)
2.有序性
在Java里面,可以通过volatile关键字来保证一定的“有序性”。另外可以通过synchronized和Lock来保证有序性,很显然, synchronized和Lock保证每个时刻是有一个线程执行同步代码,相当于是让线程顺序执行 同步代码,自然就保证了有序性。
Java内存模型具备一些先天的“有序性”,即不需要通过任何手段就能够得到保证的有序性,这个通常也称为happens-before 原则。
volatile能实现有序性是因为Lock前缀,Lock不是一种内存屏障,但是它能完成类似内存屏障的功能。Lock会对
![](https://i-blog.csdnimg.cn/blog_migrate/4de0414cc3e8ce80af514c2b1b6fa132.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3cc412d671545b25936c4b858ec156b7.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5701a06a1d998c8d7ede07352748e699.png)
偏向锁:
6.2 线程的实现方式
(1)继承Thread类
1. 定义一个Thread类的子类,重写run方法,将相关逻辑实现,run()方法 就是线程要执行的业务逻辑方法
2. 创建自定义的线程子类对象
1. 创建实现Callable接口的类myCallable
2. 以myCallable为参数创建FutureTask对象
3. 将FutureTask作为参数创建Thread对象
6.3 线程池中常用的方法
![](https://i-blog.csdnimg.cn/blog_migrate/4b0ecb7dcc945d3ed57a335c9377d331.png)
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
![](https://i-blog.csdnimg.cn/blog_migrate/0aa430cc1f0765ab0f8b181385327f17.png)
execute方法,代码里的大致内容可由下图来表示:
![](https://i-blog.csdnimg.cn/blog_migrate/9c778c4ba5396f9ffa11dee0ccaa8a6d.png)
addWorker方法的主要工作是在线程池中创建一个新的线程并执行,firstTask参数 用于指定新增的线程执行的第一个任务,core参数为true表示在新增线程时会判断当前活动线程数是否少于corePoolSize,false表示新增线程前需要判断当前活动线程数是否少于maximumPoolSize。
runWorker方法
- while循环不断地通过getTask()方法获取任务;
- getTask()方法从阻塞队列中取任务;
- 如果线程池正在停止,那么要保证当前线程是中断状态,否则要保证当前线程不是中断状态;
- 调用task.run()执行任务;
- 如果task为null则跳出循环,执行processWorkerExit()方法;
- runWorker方法执行完毕,也代表着Worker中的run方法执行完毕,销毁线程。
从execute方法开始,Worker使用ThreadFactory创建新的工作线程,runWorker通过getTask获取任务,然后执行任务,如果getTask返回null,进入processWorkerExit方法,整个线程结束,如图所示:
七:并发容器之ThreadLocal详解
原理:线程局部变量是局限于线程内部的变量,属于线程自身所有,不在多个线程间共享。Java提供ThreadLocal类来支持线程局部变量,是一种实现线程安全的方式。
注意点:在管理环境下(如 web 服务器)使用线程局部变量的时候要特别小心,在这种情况下,工作线程的生命周期比任何应用变量的生命周期都要长。任何线程局部变量一旦在工作完成后没有释放,Java 应用就存在内存泄露的风险。
使用场景:为每个线程分配一个 JDBC 连接 Connection。
ThreadLocal造成内存泄漏的原因: