前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java并行-0.基本概念

Java并行-0.基本概念

作者头像
悠扬前奏
发布2019-05-28 20:37:50
5210
发布2019-05-28 20:37:50
举报
文章被收录于专栏:悠扬前奏的博客

1. 同步(Synchonous)和异步(Asynchronous)

同步和异步是用来形容一次方法调用的:

  • 同步方法开始后,调用者必须等到方法结束才能进行后续的行为;
  • 异步方法开始后,方法调用立即返回,调用者继续后续的行为,异步调用的方法完成后,再通知调用者。

2. 并发(Concurrency)和并行(Parallelism)

并发和并行指的是两个或者多个任务一起执行:

  • 并发指的是短时间内多个任务交替执行
  • 并行指的是多个任务同时执行

3.临界区

临界区表示被多个线程使用的公共资源,但是每一次只能有一个线程使用它。 比如打印机资源。

4.阻塞(Blocking)和非阻塞(Non-Blocking)

阻塞和非阻塞用来形容多线程之间的相互影响:

  • 如果一个线程占用了临界区资源,其他所有需要这个资源的线程就需要在这个临界区中等待,这就导致了这些线程的挂起,这种情况就是阻塞。
  • 如果没有一个线程能够妨碍其他线程的执行,这种情况就是非阻塞。

5.死锁(Deadlock),饥饿(Starvation)和活锁(Livelock)

死锁,饥饿,活锁,属于多线程情况下的线程活跃性问题:

  • 死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。 此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
  • 饥饿指的是某一个或者多个线程无法获得说需要的资源,导致一直无法执行。 可能的情况包括线程优先级过低,某线程长时间占用关键资源等。 与死锁相比,饥饿是可能在未来一段时间内解决的。
  • 活锁指的是资源不断在两个或者多个线程中跳动,没有一个线程可以同时拿到所有的资源而正常执行。

6.并发级别

由于临界区(资源)的存在,多线程之间的并发是受到控制的,并发的级别被分为:阻塞,无饥饿,无障碍,无锁,无等待五种:

6.1 阻塞(Blocking)

一个线程是阻塞的,那么在其他线程释放资源之前,当前线程无法继续执行。 例如在使用了synchronized关键字,或者重入锁,得到的就是阻塞的线程。它们会在执行后续代码之前,得到临界区的锁,如果得不到,线程会挂起等待,直到占有了说需要的资源。 这是一种悲观的策略,认为两个线程之间很有可能发生冲突,以保护共享数据为第一优先级。

6.2 无饥饿(Starvation-Free)

线程之间如果有优先级,线程调度的时候就会优先满足高优先级的线程,即,对于同一个资源的分配,是不公平的。 对于非公平的锁来说,系统优先满足高优先级的线程,就可能会导致低优先级的线程产生饥饿; 如果锁是公平的,满足先来后到,那么就没有饥饿产生,所有的线程都有机会执行。

6.3无障碍(Obstruction-Free)

两个线程如果是无障碍的执行,那么它们不会因为临界区(资源)的问题导致一方被挂起。 这是一种最弱的非阻塞调度。一旦发生数据竞争,需要进行数据回滚。 这是一种乐观的策略,认为系统之间发生冲突的可能性不大,以读取为第一优先级,产生冲突了再进行回滚。 无障碍可以以来一个“一致性标记”来实现:线程修改数据之前,对“一致性标记”进行修改,表明数据不再安全。其他线程读取后发现一致性标记不同,就知道资源的访问产生了冲突,需要进行回滚。

6.4 无锁(Lock-Free)

无锁的情况下,所有下次你很都能尝试对临界区进行访问,需要保证必然有一个线程能够在有限步内完成操作,离开临界区。其并行都是无障碍的。

6.5 无等待(Wait-Free)

无等待的情况下,所有的操作都必须在有限步内完成。 可以分为“有界无等待”和“线程无关的无等待”,区别在于循环次数的限制不同。

7 原子性(Atomicity),可见性(Visibillity),有序性(Ordering),Happen-Before原则

  • 原子性是指一个操作是不可中断的。
  • 可见性是指当一个线程修改了某一个共享变量的值,其他线程能否立即知道这个修改。
  • 有序性是指线程A的指令执行顺序在线程B看来是没有保证的。不过对于一个线程来说,它看到的指令执行顺序是一致的。 有序性产生的原因是程序执行的时候,可能会进行指令重排。
  • Happen-Before原则是指令重排中不可违背的原则:
    • 程序顺序原则:一个线程内保证语义的串行性
    • volatile原则:volatile变量的写,先发生于读,这样保证了volatile变量的可见性
    • 锁规则:解锁(unlock)必然发生在随后的加锁(lock)前
    • 传递性:A先于B,B先于C,则A必然先于C *线程的start()方法优先于它的每一个动作
  • 线程的所有操作优先于线程的终结(Thread.join())
  • 线程的中断(interrupt())先于被中断线程的代码
  • 对象的构造函数执行,结束先于finalize()方法
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.12.05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 同步(Synchonous)和异步(Asynchronous)
  • 2. 并发(Concurrency)和并行(Parallelism)
  • 3.临界区
  • 4.阻塞(Blocking)和非阻塞(Non-Blocking)
  • 5.死锁(Deadlock),饥饿(Starvation)和活锁(Livelock)
  • 6.并发级别
    • 6.1 阻塞(Blocking)
      • 6.2 无饥饿(Starvation-Free)
        • 6.3无障碍(Obstruction-Free)
        • 6.4 无锁(Lock-Free)
          • 6.5 无等待(Wait-Free)
          • 7 原子性(Atomicity),可见性(Visibillity),有序性(Ordering),Happen-Before原则
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档