并发编程的其它基础

2.1什么是多线程编程

我也不知道,哈哈哈,就是保证线程安全吧

2.2为什么要多线程编程

快呗

2.3Java中的线程安全问题

指:多个线程同时读写一个共享资源并且没有任何同步措施时,导致出现脏数据或者其它不可预见的结果的问题

2.4内存可见性问题

java内存模型:概念模型

所有的变量都放在主内存中,当线程需要使用变量时,会把主内存里面的变量赋值到自己的工作空间或者叫作工作内存中,线程读写变量时操作的是自己工作内存中的变量

真实模型:

2.5sychronized关键字

锁:当阻塞一个线程时,需要从用户态切换到内核态,浪费时间。JDK1.6之后有所更改

工作方式:进入到sunchronized快时,将需要的变量从线程的工作内存中清除,这样在synchronized块内使用到该变量时就不会从线程的工作内存中获取,而是直接去主存中获取。退出时,将sychronized中的共享变量修改复制到主内存中

2.6Java中的volatile关键字

工作方式:当一个变量被声名为volatile时,线程在写入变量时不会把指缓存在寄存器或者其它地方,而是把值刷新回主内存。供其它线程读取

不保证原子性,所以也是不安全的,但是什么时候用呢?

  • 写入变量值不依赖变量的当前值时,因为如果依赖当前值,将是获取-计算-写入三部操作,
  • 读写变量时没加锁。

2.7Java中的原子操作

要么全部执行,要么全部不执行

2.8Java中的CAS操作

就是比较之后修改的过程,也就是,先读取,然后准备修改主存中的值时,查看当前的值是不是之前读取的值,如果不是,那么重新读写。

ABA问题:就是你读之前是A,你修改为A+1;但是当你写之前,有个线程将A修改为了B,又修改为了A,其实是变了,但是并不知道变过,还是将A+1写了;其实是没什么问题,但是难免会有什么问题啊!

2.9Unsafe类

其实并不允许程序员使用,但是可以通过反射来实例化Unsafe类来使用

提供了一些硬件级别的方法:然后一个字就是执行起来很快。其实CAS不是绝对安全的嘛,但是只要写的速度够快,其实相对来说是安全的。绝对的安全应该是深入到操作系统,直接锁变量才是绝对安全的!

2.10指令重排

java----jvm指令----会进行指令重新排序;这种重新排序有时候会造成多线程的错误;volatile是避免指令重排的。

2.11伪共享

概念:cpu读取缓存行的时候,一次读一行,一行中有好多的变量;有可能多个线程分别需要一行中的不同变量;假如线程1修改了缓存行的内容,那么就造成线程2需要去重新读取了。

解决办法:一个变量占据一行!

  1. 手动添加一些无用的变量,扩充到一行
  2. 或者使用jdk提供的@sun.misc.Contended注解来标明变量占据一行,当然默认这个注解是核心类用的,可以通过jvm指令设置一下。

当多线程访问同一个缓存行的多个变量时才会出现伪共享

2.12锁的概述

乐观锁和悲观锁

公平锁和非公平锁

独占锁和共享锁

什么是可重入锁

自旋锁

这个应该都不用写了吧,反正我会。

猜你喜欢

转载自www.cnblogs.com/sicheng-li/p/13200227.html