并发编程多线程基础(草稿3)

第一节
  • volatile与synchronized最大的区别就是volatile保证了可见性,但是不能保证原子性(线程安全),而synchronized即保证了原子性,又保证了可见性。
  • volatile禁止重排序功能,但是synchronized不会禁止重排序
  • volatile与synchronized的区别:(重要)
    (1)synchronized保证了内存的可见性和操作的原子性
    (2)volatile只能够保证线程的可见性
    (3)volatile不需要加锁,比synchronized更加轻量级,并不会阻塞线程,但是synchronized可能会造成线程的阻塞。
    (4)volatile标记的变量不会被编译器优化(即不支持重排序功能),而synchronized则支持重排序,可以被编译器优化。
    (5)volatile是变量修饰符,仅能够修饰变量,而synchronized是一个方法或块的修饰符。
  • 重排序概念:CPU会对代码实现进行优化,但是其不会对有依赖关系做重排序。(重排序如果有影响也是在多线程的情况下才会有影响),重排序会使代码的执行的顺序可能发生改变,但是执行的结果不会发生任何改变。
  • 什么是数据的依赖关系:
    (1)
int a = 1;
int b = 2;
int c = a*b

此时a和b的赋值就是互不影响的

第二节
  • as-if-serial语义:无论怎么做重排序,但是目的都是提高并行度,不能影响到正常的结果
  • 重排序一般在多线程的情况下遇到。
  • 加入volatile可以禁止重排序
  • 举例说明:
double pi = 3.14;// A
double r = 1.0; // B
double area = pi*r*r; // C

根据上面的代码我们可以对其进行分析,A与C之间存在依赖关系,所以C不能排到A的前面,同时B与C之间也存在依赖关系。所以C也不能排到B的前面。但是A与B之前是不存在依赖关系的,所以A与B是可以进行重排序的。

  • happens-before的定义:
    (1)如果一个操作happens-before另一个操作,那么第一个操作的执行结果对第二个操作可见,而且第一个操作的执行顺序排在第二个操作之前。
    (2)两个操作之间存在happens-before关系,并不意味着java平台的具体实现必须按照happens-before关系指定的顺序来执行,如果重排序之后的执行结果,与按照happens-before关系来执行的结果一直,那么这种重排序并不非法。
    注意:
    (1)上面1是JMM对程序员的承诺。从程序员的角度来说,可以这样理解happens-before关系:如果A happens-before B,那么Java内存模型将向程序员保证–A操作的结果将对B可见,且A的执行顺序排在B之前,注意,这只是Java内存模型向程序员做出的保证。
    (2)上面2是JMM对编译器和处理器重排序的约束,JMM其实是在遵循一个基本的原则:只要不改变程序的执行结果,编译器和处理器怎么优化都行。happens-before这么做的目,都是为了在不改变程序执行结果的前提下,尽可能的提高执行的并行度。(保证了as-if-serial)

  • happens-before规则
    (1)程序顺序规则:一个线程中的每个操作,happens-before于该线程中的任意后续操作。
    (2)监视器锁规则:对一个锁的解锁,happens-before于随后对这个锁的加锁
    (3)volatile变量规则:(volatile会使其禁止重排序)对一个volatile域的写,happens-before于任意后续对这个volatile域的读。即写发生在读之前
    (4)传递性:如果A happens-before B, 且B happens-before C,那么A happens-before C

第三节
  • 多线程之间的通信,wait和notify,对象锁池
  • wait释放当前的锁,当前线程等待
  • notify唤醒当前等待的线程
  • wait和notify必须是在同步方法中使用,即synchronized中使用
  • 生产者其实是是向共享数据中写操作,消费者是向共享内存中的读数据。
  • 加锁的时候,不仅要在生产者加锁,消费者读数据的时候也要加锁,因为有可能读了一半,另一个线程已经修改了变量,这样子读取数据是错误的。
第四节
  • wait和notify,常用的线程的通信机制
  • wait和notify使用的时候一定要在同步方法或者同步代码块中。并且一定要持有同一把锁。
  • wait是让当前线程等待,释放锁的资源
  • notify唤醒当前对象锁池被等待的资源,这里就是必须是同一把锁的原因,释放的是当前锁对象池中所有等待的资源。
  • 一般synchronized锁哪个对象,哪个对象调用wait和notify(重要
  • wait和notify都是object的方法,synchronized锁哪个对象,哪个对象调用wait和notify
  • notifyall唤醒所有的当前锁池中的线程
  • wait与join的区别
    (1)join无需唤醒(join底层使用的是wait,也会释放锁对象
    (2)wait用在同步中
  • wait与sleep的区别
    (1)sleep不会释放锁
    (2)sleep是Thread的方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值