![](https://img-blog.csdnimg.cn/20200510095602218.jpg?x-oss-process=image/resize,m_fixed,h_224,w_224)
Java并发教程2020版
最新2020版Java并发和多线程教程~
每天滚动翻译哦。
知识进步,从关注开始~
GentlemanTsao
android软件专家,移动终端研发15年。
技术领域:Android,qualcom modem,Java
展开
-
2020版java并发和多线程教程(一),序章(多线程,多任务,并发的概念)
原文:http://tutorials.jenkov.com/java-concurrency/index.html作者:Jakob Jenkov,2020-03-29翻译:GentlemanTsao,2020-4-1java并发这一术语涵盖了java平台的多线程、并发、并行,包括java并发工具,问题和解决办法。本教程涉及到java多线程相关的核心概念、并发结构、并发问题、并发的成本和收益...翻译 2020-04-03 14:44:08 · 451 阅读 · 0 评论 -
2020版java并发和多线程教程(二):多线程的好处(CPU使用,程序设计,程序响应,资源分配)
作者:Jakob Jenkov,2019-11-20翻译:GentlemanTsao,2020-4-7多线程最明显的好处有:更好的使用CPU;某些情况下让程序设计更简单;让程序更好的响应;让CPU资源在不同任务间分配的更均衡。Better CPU UtilizationImagine an application that reads and processes files fro...翻译 2020-04-11 22:03:45 · 488 阅读 · 0 评论 -
2020版java并发和多线程教程(三):多线程的代价(程序设计,上下文切换,资源消耗)
作者:Jakob Jenkov,2019-11-20翻译:GentlemanTsao,2020-4-14把程序从单线程转变到多线程并非仅仅带来好处,也需付出代价。我们不应该一味的让程序支持多线程,而只应在权衡了利大于弊的情况使用多线程。当我们不能确定时,可以先试着衡量下程序的性能和响应性,而不是凭空猜想。多线程的设计更复杂虽然多线程程序的某些部分比单线程更简单,但是其他部分更复杂。多线程代...翻译 2020-04-14 10:08:00 · 421 阅读 · 0 评论 -
2020版java并发和多线程教程(四),并发模型(共享状态,分离状态,并行工作机模型,流水线模型,反应/事件驱动系统,函数式并行)
作者:Jakob Jenkov,2019-11-21翻译:GentlemanTsao,2020-4-14并发系统可以由不同的并发模型来实现。并发模型规定了系统中线程的协作方式,从而能够共同完成指定任务。不同的并发模型会将任务按不同的方式分割,而线程之间也通过不同的方式来通信和协作。本并发教程将更深入一点的讨论时下(2015 - 2019)使用最普遍的并发模型。Concurrent syste...翻译 2020-04-19 21:31:41 · 443 阅读 · 0 评论 -
2020版java并发和多线程教程(五):类单线程(单线程扩展,无共享状态,负载分配,线程通信)
类单线程是这样一种并发模型,它把一个单线程系统扩展到N个单线程系统,结果是N个单线程系统并行运行。 类单线程系统不是纯粹的单线程系统,因为它包含多个线程。但是,每个线程都像单线程系统一样运行。因此称之为类单线程而不是单线程。 ## 为什么要用单线程系统? 你可能好奇,为什么时至今日还有人会设计单线程系统。单线程系统之所以受欢迎,是因为其并发模型比多线程系统简单得多。单线程系统不与其他线程共享任何状态(对象/数据)。翻译 2020-04-23 20:54:51 · 364 阅读 · 0 评论 -
2020版java并发和多线程教程(六):并发和并行
作者:Jakob Jenkov,2020-03-29翻译:GentlemanTsao,2020-4-24并发和并行这两个术语通常用于多线程程序。但并发和并行到底是什么意思,这两个术语又有什么不同呢?我花了一些时间才最终理解并发和并行之间的区别。因此,我打算在本Java并发教程中添加一篇关于并发与并行的文章。并发并发意味着一个应用程序同时(并发)在多个任务上进行。当然,如果计算机只有一个C...翻译 2020-04-24 21:08:34 · 265 阅读 · 0 评论 -
2020版java并发与多线程教程(七):创建并启动java线程(Thread,Runnable,线程名称 ,暂停和停止线程)
作者:Jakob Jenkov,2020-03-29翻译:GentlemanTsao,2020-4-26Java线程就像一个虚拟CPU,可以在Java应用程序中执行Java代码。当Java应用程序启动时,它的main()方法由主线程执行,主线程是Java虚拟机为运行应用程序而创建的一个特殊线程。你可在应用程序内部创建和启动更多的线程,这些线程可以与主线程并行执行应用程序的部分代码。和其他Java对象一样,Java线程也是对象。线程是java.lang.Thread类的实例,或者是该类的子类的实例。翻译 2020-04-26 20:58:50 · 606 阅读 · 0 评论 -
2020版java并发和多线程教程(八):竞态条件和临界区
作者:Jakob Jenkov,2020-04-6翻译:GentlemanTsao,2020-4-27竞态条件是可能发生在临界区内的特殊条件。临界区是由多个线程执行的一段代码,它的并发执行结果会因线程的执行顺序而有差别。多个线程执行一个临界区,可能因线程执行的顺序不同而带来不同的结果,在这种情况下,该临界区称为含有竞态条件。术语竞态条件源于这样一个隐喻,即线程在争抢临界区,而争抢的结果会影响临界区的执行结果。这听起来可能有点复杂,所以我将在下面的章节中详细介绍竞态条件和临界区。临界区翻译 2020-04-27 20:28:56 · 510 阅读 · 0 评论 -
2020版java并发和多线程教程(九):线程安全和共享资源(局部变量,局部对象引用,对象成员变量,线程控制逸出规则)
翻译:GentlemanTsao,2020-4-29可以由多个线程同时安全调用的代码称为线程安全代码。线程安全的代码不包含竞态条件。只有当多个线程更新共享资源时,才会出现竞态条件。因此,了解Java线程在执行时共享了哪些资源非常重要。局部变量局部变量存储在线程自己的堆栈中。这意味着局部变量永远不会在线程之间共享。这也意味着所有的原始局部变量都是线程安全的。以下是线程安全的原始局部变量的示例:翻译 2020-04-29 21:22:41 · 400 阅读 · 0 评论 -
2020版java并发和多线程教程(十):线程安全和不变性
只有当多个线程访问同一资源,并且一个或多个线程写入该资源时,才会出现竞态条件。如果多个线程读取同一资源,则不会出现竞态条件。我们可以使共享对象不可变,以此来确保线程之间共享的对象不会被任何线程更新,从而保证线程安全。下面是一个例子:public class ImmutableValue{ private int value = 0; public ImmutableValue(in...翻译 2020-04-30 21:11:21 · 258 阅读 · 0 评论 -
2020版Java并发和多线程教程(十一):Java内存模型(内存模型,硬件内存架构,共享对象的可见性,竞态条件)
翻译:GentlemanTsao,2019-05-07Java内存模型规定了Java虚拟机使用计算机内存(RAM)的方式。Java虚拟机是整个计算机的一种模型,所以这个模型自然包含一个内存模型,也就是Java内存模型。要想设计出正确的并发程序,理解Java内存模型非常重要。Java内存模型规定了不同线程用何种方式、以及何时可以看到其他线程写入共享变量的值,以及在必要时如何同步对共享变量的访问。原始的Java内存模型有很多不足,所以在Java 1.5中Java内存模型得到了完善。而Java8仍沿用了翻译 2020-05-09 19:41:13 · 283 阅读 · 0 评论 -
2020版Java并发和多线程教程(十二):Java同步块(synchronized关键字,四种同步块,数据可见性,指令重排,性能开销,可重入性)
从我4月初开始翻译这部教程到现在,已经有1个半月的时间了。已翻译的内容大约有三分之一以上。由于在翻译过程中,每个段落平均要读五遍,因而耗费了不少时间。而我又是个崇尚劳逸结合的懒人,只能抽出有限的空余时间。所以按照这个进度,完成这个教程应该还要两三个月。还请对该教程感兴趣的朋友保持耐心~另外,如果认真阅读的你发现了错误,请告诉我以便及时纠正。我们何不众筹一部教程?Java同步块将方法或代码块标记为synchronized。Java中的同步块一次只能在一个线程中执行(取决于你如何使用它)。因此,可以使翻译 2020-05-17 20:43:22 · 310 阅读 · 0 评论 -
2020版Java并发和多线程教程(十三):Java volatile关键字(变量可见性,可见性规则,指令重排序,Happens-Before规则)
翻译:GentlemanTsaoJava volatile关键字用于将Java变量标记为“存储在主内存中”。更确切地说,这意味着:volatile变量每次都将从计算机的主存储器读取,而不是CPU缓存中;volatile变量每次都将写入主存储器,而不仅仅是CPU缓存。实际上,从Java5开始,volatile关键字保证的不仅仅是volatile变量从主内存读取和写入。我将在下面的章节中解释这一点。变量可见性问题Java volatile关键字保证了跨线程变量更改的可见性。这听起来可能有点抽象,所以让我翻译 2020-05-20 20:18:02 · 322 阅读 · 0 评论 -
2020版Java并发和多线程教程(十四):Java ThreadLocal(泛型类型,supplier接口,延后设置,InheritableThreadLocal)
系列专栏:java并发和多线程教程2020版Java ThreadLocal类可以创建只能由同一个线程读写的变量。因此,即使两个线程正在执行相同的代码,并且代码引用了相同的ThreadLocal变量,两个线程也无法看到彼此的ThreadLocal变量。因此,Java ThreadLocal类提供了一种使代码线程安全的简单方法,而没有这个方法则线程不是安全的。创建ThreadLocal创建一个ThreadLocal实例就像创建其他Java对象一样,通过new操作符。下面的示例演示了如何创建Th...翻译 2020-05-21 22:38:56 · 747 阅读 · 0 评论 -
2020版Java并发和多线程教程(十五):线程信号传递(忙等待,wait、notify、notifyall,信号丢失,虚假唤醒)
线程信号传递的目的是使线程能够相互发送信号。另外,线程信号传递使线程能够等待来自其他线程的信号。例如,线程B可能会等待线程a发出的的信号,指示数据已准备好待处理。通过共享对象发送信号线程相互发送信号的一种简单方法是在某个共享对象变量中设置信号值。线程A可以在同步块内将布尔成员变量hasDataToProcess设置为true,线程B也可以在同步块内读取hasDataToProcess成员变量。下面是一个简单的对象示例,它可以保存这样的信号,并提供设置和检查它的方法:public class MySig翻译 2020-05-25 21:00:55 · 569 阅读 · 0 评论 -
2020版Java并发和多线程教程(十六):死锁(DeadLock,线程死锁,数据库死锁)
线程死锁死锁是指两个或多个线程被阻塞,等待获得死锁中其他一些线程所持有的锁。当多个线程同时需要相同的锁,但以不同的顺序获取它们时,可能会发生死锁。例如,如果线程1锁定A并试图锁定B,而线程2已经锁定B并试图锁定A,则会出现死锁。线程1永远得不到B,线程2永远得不到A。此外,他们都不会知道。他们将永远被阻塞在他们各自的对象上,A和B。这种情况就是死锁。这种情况如下所示:Thread 1 locks A, waits for BThread 2 locks B, waits for A下面的示例翻译 2020-05-26 21:56:04 · 303 阅读 · 0 评论 -
2020版Java并发和多线程教程(十七):防范死锁(锁排序,锁超时,死锁检测)
在某些情况下,可以防止死锁。我将在本文中描述三种技术:锁排序当多个线程需要相同的锁但以不同的顺序获取它们时,就会发生死锁。如果确保任何线程始终以相同的顺序获取所有锁,则不会出现死锁。翻译 2020-05-27 21:31:08 · 731 阅读 · 0 评论 -
2020版Java并发和多线程教程(十八):饥饿与公平性(线程饥饿,锁,公平锁)
如果某个线程因为其他线程抢占了所有时间而没有获得CPU时间,则称为“饥饿”。 该线程“因饥饿而死亡”,因为其他线程占用了CPU时间而它却得不到。 饥饿的解决方案称为“公平性”——所有线程都被公平地给予执行的机会。java中饥饿的原因以下三个常见原因可能导致Java中的线程的饥饿:高优先级的线程会吞噬低优先级的线程的所有CPU时间。线程会无限期地等待着进入同步块,因为在它之前始终有其他线程被允许访问同步块。在某个对象上等待的线程(在该对象上调用wait())一直无限期地等待,因为其他线程会不断被唤翻译 2020-05-28 21:20:40 · 468 阅读 · 0 评论 -
2020版Java并发和多线程教程(十九):嵌套管程锁死
嵌套管程锁死是如何发生的嵌套管程锁死的问题类似于死锁。 嵌套管程锁死是这样发生的:Thread 1 synchronizes on AThread 1 synchronizes on B (while synchronized on A)Thread 1 decides to wait for a signal from another thread before continuingThread 1 calls B.wait() thereby releasing the lock on B,翻译 2020-05-30 21:58:14 · 663 阅读 · 0 评论 -
2020版Java并发和多线程教程(二十):滑移条件(Slipped Conditions)
滑移条件是指,一个线程从检查了某个条件到对其执行操作的时间内,该条件被另一个线程更改,从而使第一个线程操作出错。 下面是一个简单的示例:请注意lock()方法包含两个同步块。 第一个块等待,直到isLocked为false。 第二个块将isLocked设置为true,以锁定Lock实例,不让其他线程访问。翻译 2020-06-03 20:21:27 · 445 阅读 · 0 评论 -
2020版Java并发和多线程教程(二十一):Java中的锁(普通锁,可重入锁,公平锁)
翻译:GentlemanTsao, 2020-06-04文章目录简单的锁锁的可重入性锁的公平性从finally子句中调用unlock()锁是一种类似于同步块的线程同步机制,但是锁比Java的同步块更复杂。 锁(以及其他更高级的同步机制)是使用同步块创建的,因此我们无法完全抛弃synchronized关键字。从Java 5开始,包java.util.concurrent.locks包含多个锁实现,因此不需要再实现自己的锁。 但是你仍然需要知道如何使用它们,并且了解其实现背后的理论仍然很有用。 有关更多详翻译 2020-06-05 13:30:48 · 242 阅读 · 0 评论 -
2020版Java并发和多线程教程(二十二):Java中的读/写锁(可重入锁,完全可重入的ReadWriteLock)
java读/写锁的实现读/写锁的可重入性读锁可重入写锁可重入读锁到写锁可重入写锁到读锁访问可重入完全可重入的ReadWriteLock从finally子句中调用unlock()翻译花絮翻译 2020-06-06 08:05:23 · 318 阅读 · 0 评论 -
2020版Java并发和多线程教程(二十三):重入锁死
重入锁死是一种类似于死锁和嵌套管程锁死的情况。 重入锁死在“锁”和“读/写锁”一文中也有涉及。如果线程重新进入Lock,ReadWriteLock或其他不可重入的同步器,则可能会发生重入锁死。 可重入是指已持有锁的线程可以重新获取该锁。 Java的同步块是可重入的。 因此,以下代码可以正常工作:public class Reentrant{ public synchronized outer(){ inner(); } public synchronized inner(){翻译 2020-06-07 09:50:33 · 229 阅读 · 0 评论 -
2020版Java并发和多线程教程(二十四):信号量(Semaphores,计数信号量,有界信号量,信号量用作锁)
翻译:GentlemanTsao,2020-06-08;简单的信号量;使用信号量传递信号;计数信号量;有界信号量;将信号量用作锁翻译 2020-06-08 21:18:25 · 290 阅读 · 0 评论 -
2020版Java并发和多线程教程(二十五):阻塞队列
阻塞队列是这样一个队列,当尝试在队列为空时出队,或者尝试在队列已满时入队,它将阻塞。 尝试从空队列中出队的线程将被阻塞,直到其他线程插入一项到队列中为止。 尝试使一个项目进入满队列的线程将被阻塞,直到某个其他线程在队列中腾出空间为止,方法是使一个或多个项目出队或完全清除队列。下面的示意图显示两个线程通过阻塞队列进行协作:Java 5在java.util.concurrent包中附带了阻塞队列实现。 可以在我的java.util.concurrent.BlockingQueue教程中了解该类。 即使Ja翻译 2020-06-09 07:15:23 · 190 阅读 · 0 评论 -
2020版Java并发和多线程教程(二十六):线程池(Thread Pool)
当需要限制应用程序中同时运行的线程数时,线程池很有用。 启动新线程会带来性能开销,并且每个线程还为其栈等分配了一些内存。与其为每个并发执行的任务启动新线程,不如将任务传递给线程池。 一旦池中有任何空闲线程,就会将任务分配给其中一个并执行。 内部实现为将任务插入到阻塞队列中,线程池中的线程从该队列中取出。 当一个新任务插入到队列后,其中一个空闲线程将它从队列中出队并执行它。 线程池中的其余空闲线程将被阻塞,等待任务出队。线程池通常用于多线程服务器中。 通过网络到达服务器的每个连接都被包装为一个任务,并传递翻译 2020-06-10 09:34:06 · 261 阅读 · 0 评论 -
2020版Java并发和多线程教程(二十七):比较交换(CAS)
比较交换是设计并发算法时使用的一种技术。 基本上,比较交换将期望值与变量的实际值进行比较,如果变量的实际值等于期望值,则将变量的值替换为新的值。 比较交换听起来可能有点复杂,但是一旦你理解了它,实际上就相当简单了,所以让我对这个话题做进一步的阐述。哪些情况需要用到比较交换在程序和并发算法中,一种常会出现的模式是“先检查后行动”模式。 当代码首先检查变量的值,然后根据该值进行操作时,将出现检查然后操作模式。 这是一个简单的示例:...翻译 2020-06-11 21:16:55 · 266 阅读 · 0 评论 -
2020版Java并发和多线程教程(二十八):同步器的结构
本篇归纳了同步器的共性结构,包括:状态;访问条件;状态改变;通知策略;检查并设置方法;设置方法;翻译 2020-06-13 06:44:55 · 229 阅读 · 0 评论 -
2020版Java并发和多线程教程(二十九):非阻塞算法(非阻塞并发数据结构、比较交换、乐观锁、共享意向修改、ABA问题、非阻塞算法模板)
并发中所谓的非阻塞算法是允许线程访问共享状态(或以其他方式进行协作或通信)而不会阻塞所涉及线程的算法。 更笼统地说,如果一个线程的挂起不会导致该算法中涉及的其他线程挂起,则该算法称为非阻塞算法。为了更好地理解阻塞和非阻塞并发算法之间的区别,我将首先说明阻塞算法,接着再说明非阻塞算法。阻塞并发算法...翻译 2020-07-17 18:06:32 · 302 阅读 · 0 评论 -
2020版Java并发和多线程教程(三十):终章:阿姆达尔定律(Amdahl‘s Law)
终章:阿姆达尔定律。《Java并发和多线程教程》翻译终于填坑了。翻译 2020-06-15 12:41:20 · 361 阅读 · 0 评论