5、Java并发性和多线程-相同线程

以下内容转自http://tutorials.jenkov.com/java-concurrency/same-threading.html(使用谷歌翻译):

相同线程(同一线程)是一种并发模型,其中单线程系统扩展到N个单线程系统。结果是并行运行的N个单线程系统。

同一个线程系统不是一个纯粹的单线程系统,因为它包含多个线程。但是,每个线程都像单线程系统一样运行。

为什么是单线程系统?

你可能会想知道为什么有人今天会设计单线程系统。单线程系统得到普及,因为它们的并发模型比多线程系统简单得多。单线程系统不与其他线程共享任何数据。这使得单线程可以使用非并发数据结构,并更好地利用CPU和CPU缓存。

不幸的是,单线程系统不能充分利用现代CPU。现代CPU通常带有2个或4个以上的内核。每个核心都可以作为一个单独的CPU。单线程系统只能使用其中一个核心,如下所示:

相同线程,单线程缩放

为了利用CPU中的所有内核,可以扩展单线程系统以利用整个计算机。

每个CPU一个线程

相同线程的系统通常在计算机中每个CPU运行一个线程。如果计算机包含4个CPU或4个内核的CPU,则运行4个同一线程系统(4个单线程系统)的实例是正常的。下图显示了这一原则:

没有共享状态

同一个线程系统看起来类似于多线程系统,因为同一个线程系统在其中运行了多个线程。但有一个微妙的区别。

同线程和多线程系统之间的区别在于同一线程系统中的线程不共享状态。没有共享内存,线程同时访问。没有并发数据结构等,线程共享数据。这个区别如下所示:

缺少共享状态是每个线程如果是单线程系统的行为。然而,由于同一线程系统可以包含多个线程,因此它不是真正的“单线程系统”。由于缺乏一个更好的名字,我发现更精确地称这个系统是一个相同的线程系统,而不是一个“单线程设计的多线程系统”。相同线程更容易说明,更容易理解。

相同线程基本上意味着数据处理保持在同一个线程内,并且同一线程系统中的线程不会同时共享数据。

负荷分配

显然,同一线程系统需要共享运行的单线程实例之间的工作负载。如果没有,只有一个实例将获得任何工作,并且该系统实际上将是单线程的。

正确分配负载在不同实例上的方式取决于系统的设计。下面我将介绍几个。

单线程微服务器

如果你的系统由多个微服务器组成,则每个微服务器都可以以单线程模式运行。当你将多个单线程微服务部署到同一台机器时,每个微服务器都可以在单个CPU上运行单个线程。

微服务不会自然地共享任何数据,所以微服务是同一线程系统的好例子。

带有分片数据的服务

如果你的系统实际上需要共享数据,或至少是数据库,则可以分割数据库。分片表示数据在多个数据库之间分配。数据通常被分割,使得彼此相关的所有数据位于同一数据库中。例如,属于某个“所有者”实体的所有数据将被插入同一数据库。分片不在本教程的范围之内,因此你将不得不搜索有关该主题的教程。

线程通信

如果同一线程中的线程需要进行通信,则通过消息传递来实现。想要向线程A发送消息的线程可以通过生成消息(字节序列)来实现。线程B可以复制该消息(字节序列)并读取它。通过复制消息线程B确保线程A在线程B读取时线程A无法修改消息。一旦它被复制,它是不可变的线程A.

通过消息传递的线程通信如下所示:

线程通信可以通过队列,管道,unix套接字,TCP套接字等进行。无论什么只要适合你的系统即可。

更简单的并发模型

在同一线程系统中自己的线程中运行的每个系统都可以像单线程那样被实现。这意味着内部并发模型比线程共享状态变得简单得多。你不必担心并发数据结构和数据结构可能导致的所有并发问题。

插图

以下是单线程,多线程和同线程系统的图示,因此你可以更容易地了解它们之间的区别。

第一个例子显示了一个单线程系统。

第二个例子显示了线程共享数据的多线程系统。

第三个例子显示了一个具有2个线程的同一线程系统,它们分开数据,通过传递消息来进行通信。

时间: 2024-10-29 10:46:59

5、Java并发性和多线程-相同线程的相关文章

Java 并发和多线程(一) Java并发性和多线程介绍[转]

作者:Jakob Jenkov 译者:Simon-SZ  校对:方腾飞 http://tutorials.jenkov.com/java-concurrency/index.html 在过去单CPU时代,单任务在一个时间点只能执行单一程序.之后发展到多任务阶段,计算机能在同一时间点并行执行多任务或多进程.虽然并不是真正意义上的“同一时间点”,而是多个任务或进程共享一个CPU,并交由操作系统来完成多任务间对CPU的运行切换,以使得每个任务都有机会获得一定的时间片运行. 随着多任务对软件开发者带来的

Java并发性和多线程介绍

以下内容转自http://ifeve.com/java-concurrency-thread/: 在过去单CPU时代,单任务在一个时间点只能执行单一程序.之后发展到多任务阶段,计算机能在同一时间点并行执行多任务或多进程.虽然并不是真正意义上的“同一时间点”,而是多个任务或进程共享一个CPU,并交由操作系统来完成多任务间对CPU的运行切换,以使得每个任务都有机会获得一定的时间片运行. 随着多任务对软件开发者带来的新挑战,程序不在能假设独占所有的CPU时间.所有的内存和其他计算机资源.一个好的程序榜

Java并发性和多线程介绍【翻译】

作者:Jakob Jenkov 译者:Simon-SZ  校对:方腾飞 http://tutorials.jenkov.com/java-concurrency/index.html 在过去单CPU时代,单任务在一个时间点只能执行单一程序.之后发展到多任务阶段,计算机能在同一时间点并行执行多任务或多进程.虽然并不是真正意义上的"同一时间点",而是多个任务或进程共享一个CPU,并交由操作系统来完成多任务间对CPU的运行切换,以使得每个任务都有机会获得一定的时间片运行. 随着多任务对软件开

6、Java并发性和多线程-并发性与并行性

以下内容转自http://tutorials.jenkov.com/java-concurrency/concurrency-vs-parallelism.html(使用谷歌翻译): 术语并发和并行性通常用于多线程程序.但是,并发和并行性究竟是什么意思呢,它们是相同的术语还是什么? 简短的答案是“不”.它们不是相同的术语,尽管它们在表面上看起来非常相似.也花了我一些时间来终于找到并了解并发和并行性之间的区别.因此,我决定在这个Java并发教程中添加一个关于并发性与并行性的文本. 并发 并发意味着

13、Java并发性和多线程-Java Volatile关键字

以下内容转自http://tutorials.jenkov.com/java-concurrency/volatile.html(使用谷歌翻译): Java volatile关键字用于将Java变量标记为“存储在主存储器”中.更准确地说,这意味着,每个读取volatile变量将从计算机的主存储器中读取,而不是从CPU缓存中读取,并且每个写入volatile变量的写入将被写入主存储器,而不仅仅是写入CPU缓存. 实际上,由于Java 5的volatile关键字保证不仅仅是volatile变量被写入

29、Java并发性和多线程-非阻塞算法

以下内容转自http://ifeve.com/non-blocking-algorithms/: 在并发上下文中,非阻塞算法是一种允许线程在阻塞其他线程的情况下访问共享状态的算法.在绝大多数项目中,在算法中如果一个线程的挂起没有导致其它的线程挂起,我们就说这个算法是非阻塞的. 为了更好的理解阻塞算法和非阻塞算法之间的区别,我会先讲解阻塞算法然后再讲解非阻塞算法. 阻塞并发算法 一个阻塞并发算法一般分下面两步: 执行线程请求的操作 阻塞线程直到可以安全地执行操作 很多算法和并发数据结构都是阻塞的.

18、Java并发性和多线程-饥饿与公平

以下内容转自http://ifeve.com/starvation-and-fairness/: 如果一个线程因为CPU时间全部被其他线程抢走而得不到CPU运行时间,这种状态被称之为“饥饿”.而该线程被“饥饿致死”正是因为它得不到CPU运行时间的机会.解决饥饿的方案被称之为“公平性”–即所有线程均能公平地获得运行机会.  下面是本文讨论的主题: 1. Java中导致饥饿的原因: 高优先级线程吞噬所有的低优先级线程的CPU时间. 线程被永久堵塞在一个等待进入同步块的状态. 线程在等待一个本身也处于

Java并发编程、多线程、线程池…

Java多线程干货系列(1):Java多线程基础http://www.importnew.com/21136.html#comment-651146 40个Java多线程问题总结http://www.importnew.com/18459.html#comment-651217 Java线程面试题 Top 50http://www.importnew.com/12773.html Java并发编程:Thread类的使用http://www.cnblogs.com/dolphin0520/p/39

17、Java并发性和多线程-避免死锁

以下内容转自http://ifeve.com/deadlock-prevention/: 在有些情况下死锁是可以避免的.本文将展示三种用于避免死锁的技术: 加锁顺序 当多个线程需要相同的一些锁,但是按照不同的顺序加锁,死锁就很容易发生. 如果能确保所有的线程都是按照相同的顺序获得锁,那么死锁就不会发生.看下面这个例子: Thread 1: lock A lock B Thread 2: wait for A lock C (when A locked) Thread 3: wait for A