博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JVM第五部分 高效并发
阅读量:5126 次
发布时间:2019-06-13

本文共 1416 字,大约阅读时间需要 4 分钟。

java 内存模型与线程

硬件内存模型

 

java内存模型

主内存vs工作内存

所有变量都在主内存(虚拟机内存的一部分),每条线程都有自己的工作内存,线程所有用到的变量都必须从主内存拷贝出来(不能直接读写主内存变量)

工作内存如何与主内存交互?

8种内存操作:(lock、uncock) (read、load) (use、assign) (store、write)配对出现

volatile关键字

两种特性:1.变量可见性(共享性,自己看法)2.禁止指令重排

可见性:更改变量,虚拟机主内存刷新后所有线程可见

指令重排:volatile boolean flag=false;

…………(其他java语句)

flag=true;

重排后f,lag初始化后立马为true;但volatile 修饰后不会

使用volatile前提条件:

1.运算结果不依赖当前值,或者能够确保只有单一线程修改变量

2.变量不需要其他状态变量参与

volatile关键字在写操作耗时,但是也比锁的总开销小

线程实现

三种方式:内核线程,用户级线程,用户加轻量级进程混合实现

内核线程状态转换开销大,程序一般使用的是内核线程的高级接口——轻量级进程(LWP)

java线程调度

两种方式:协同式线程调度(效果极差),抢占式线程调度(协同分配时间)

java线程定义优先级,实现给某些进程更多时间,但是不太靠谱,java优先级与系统优先级不是一一对应

状态转换

新建-运行-等待-阻塞-结束

java线程安全与锁优化

5类

1.不可变

final关键字修饰的对象、属性

2.绝对线程安全

api实现同步,但是绝对线程安全不是绝对的线程安全

vector get() remove()方法,get(i)同时remove(i),那么,抛出数组越界异常

3.线程相对安全

我们通常说的线程安全,需要保证对象单独的操作是线程安全的,我们调用时不需要额外做保证。但是,特定顺序的连续调用,也可能额外同步手段

4.线程兼容

对象本身不是线程安全,调用端正确使用同步手段保证

5.线程对立

不可能实现多线程安全的代码

线程安全实现方法 

1.互斥同步(悲观策略)

互斥方法:临界区 互斥量 信号量

synchronized

2.非阻塞同步(乐观策略)

3.无同步方案

a.可重入代码(返回结果可预测)

 b.线程本地储存

锁优化

1.自旋锁与自适应自旋

无法获取锁时,自旋等待一直请求,短时间内可以获得很好收益(避免线程切换开销),自旋次数到达限定次数后,挂起。

2.锁消除

检测到不存在竞争,消除锁(不存在竞争还加锁?api中也有很多锁,比如stringBUffer.append()),stringBUffer.append(s1),stringBUffer.append(s2),stringBUffer.append(s3),三个锁,可以被消除

3.锁粗化

同一个对象反复加锁,那么加锁同步范围扩大,还是上面的stringBUffer.append()),stringBUffer.append(s1),stringBUffer.append(s2),stringBUffer.append(s3),锁粗化后只剩第一个锁。

4.轻量级锁(看书)

5.偏向锁(看书)

 

转载于:https://www.cnblogs.com/zhijianhu/p/8811262.html

你可能感兴趣的文章
JAVA8方法引用
查看>>
js中数组的字符串表示
查看>>
优先队列实现哈弗曼最小权值
查看>>
datetime
查看>>
一种达到人工批改效果的英语语法自动纠错的方法
查看>>
os模块
查看>>
spring mvc 解决 Could not open ServletContext resource [/WEB-INF/dispatcher-servlet.xml] 异常
查看>>
Java对象内存管理
查看>>
Python练习题 005:三个数字由大到小排序输出
查看>>
【转】Js正则表达式
查看>>
(第十二周)团队项目18
查看>>
计算机组成原理之流水线处理器
查看>>
操作系统-死锁(重要)
查看>>
UUID随机字符串
查看>>
算法提高 P0102
查看>>
Golang 中的坑 一
查看>>
2.servlet
查看>>
传感器数据的拟合
查看>>
异或链表(XOR linked list)
查看>>
利用etcd及confd实现配置自动管理
查看>>