Java 编程语言的线程模型可能是此语言中最薄弱的部分。它完全不适合实际复杂程序的要求,而且也完全不是面向对象的。本文建议对 Java 语言进行重大修改和补充,以解决这些问题。
Java 语言的线程模型是此语言的一个最难另人满意的部分。尽管 Java 语言本身就支持线程编程是件好事,但是它对线程的语法和类包的支持太少,只能适用于极小型的应用环境。
关于 Java 线程编程的大多数书籍都长篇累牍地指出了 Java 线程模型的缺陷,并提供了解决这些问题的急救包(Band-Aid/邦迪创可贴)类库。我称这些类为急救包,是因为它们所能解决的问题本应是由 Java 语言本身语法所包含的。从长远来看,以语法而不是类库方法,将能产生更高效的代码。这是因为编译器和 Java 虚拟器 (JVM) 能一同优化程序代码,而这些优化对于类库中的代码是很难或无法实现的。
Allen Holub 指出,在我的《Taming Java Threads 》(请参阅 参考资料 )书中以及本文中,我进一步建议对 Java 编程语言本身进行一些修改,以使得它能够真正解决这些线程编程的问题。本文和我这本书的主要区别是,我在撰写本文时进行了更多的思考, 所以对书中的提议加以了提高。这些建议只是尝试性的 -- 只是我个人对这些问题的想法,而且实现这些想法需要进行大量的工作以及同行们的评价。但这是毕竟是一个开端,我有意为解决这些问题成立一个专门的工作组,如果您感兴趣,请发 e-mail 到 threading@holub.com 。一旦我真正着手进行,我就会给您发通知。
这里提出的建议是非常大胆的。有些人建议对 Java 语言规范 (JLS)(请参阅参考资料 )进行细微和少量的修改以解决当前模糊的 JVM 行为,但是我却想对其进行更为彻底的改进。
在实际草稿中,我的许多建议包括为此语言引入新的关键字。虽然通常要求不要突破一个语言的现有代码是正确的,但是如果该语言的并不是要保持不变以至于过时的话,它就必须能引入新的关键字。为了使引入的关键字与现有的标识符不产生冲突,经过细心考虑,我将使用一个 ($) 字符,而这个字符在现有的标识符中是非法的。(例如,使用 $task,而不是 task)。此时需要编译器的命令行开关提供支持,能使用这些关键字的变体,而不是忽略这个美元符号。
task(任务)的概念
Java 线程模型的根本问题是它完全不是面向对象的。面向对象 (OO) 设计人员根本不按线程角度考虑问题;他们考虑的是同步 信息 异步 信息(同步信息被立即处理 -- 直到信息处理完成才返回消息句柄;异步信息收到后将在后台处理一段时间 -- 而早在信息处理结束前就返回消息句柄)。Java 编程语言中的 Toolkit.getImage() 方法就是异步信息的一个好例子。 getImage() 的消息句柄将被立即返回,而不必等到整个图像被后台线程取回。
这是面向对象 (OO) 的处理方法。但是,如前所述,Java 的线程模型是非面向对象的。一个 Java 编程语言线程实际上只是一个run() 过程,它调用了其它的过程。在这里就根本没有对象、异步或同步信息以及其它概念。
对于此问题,在我的书中深入讨论过的一个解决方法是,使用一个Active_object。 active 对象是可以接收异步请求的对象,它在接收到请求后的一段时间内以后台方式得以处理。在 Java 编程语言中,一个请求可被封装在一个对象中。例如,你可以把一个通过 Runnable 接口实现的实例传送给此 active 对象,该接口的 run() 方法封装了需要完成的工作。该 runnable 对象被此 active 对象排入到队列中,当轮到它执行时,active 对象使用一个后台线程来执行它。
在一个 active 对象上运行的异步信息实际上是同步的,因为它们被一个单一的服务线程按顺序从队列中取出并执行。因此,使用一个 active 对象以一种更为过程化的模型可以消除大多数的同步问题。
在某种意义上,Java 编程语言的整个 Swing/AWT 子系统是一个 active 对象。向一个 Swing 队列传送一条讯息的唯一安全的途径是,调用一个类似SwingUtilities.invokeLater() 的方法,这样就在 Swing 事件队列上发送了一个 runnable 对象,当轮到它执行时, Swing 事件处理线程将会处理它。
那么我的第一个建议是,向 Java 编程语言中加入一个task (任务)的概念,从而将active 对象集成到语言中。( task的概念是从 Intel 的 RMX 操作系统和 Ada 编程语言借鉴过来的。大多数实时操作系统都支持类似的概念。)
一个任务有一个内置的 active 对象分发程序,并自动管理那些处理异步信息的全部机制。
定义一个任务和定义一个类基本相同,不同的只是需要在任务的方法前加一个asynchronous 修饰符来指示 active 对象的分配程序在后台处理这些方法。
所有的写请求都用一个dispatch() 过程调用被放在 active-object 的输入队列中排队。在后台处理这些异步信息时出现的任何异常 (exception) 都由 Exception_handler 对象处理,此 Exception_handler 对象被传送到 File_io_task 的构造函数中。
这种基于类的处理方法,其主要问题是太复杂了 -- 对于一个这样简单的操作,代码太杂了。向 Java 语言引入$task 和 $asynchronous 关键字后,就可以按下面这样重写以前的代码:
注意,异步方法并没有指定返回值,因为其句柄将被立即返回,而不用等到请求的操作处理完成后。所以,此时没有合理的返回值。对于派生出的模型,$task 关键字和 class 一样同效: $task 可以实现接口、继承类和继承的其它任务。标有 asynchronous 关键字的方法由 $task 在后台处理。其它的方法将同步运行,就像在类中一样。
$task关键字可以用一个可选的 $error 从句修饰 (如上所示),它表明对任何无法被异步方法本身捕捉的异常将有一个缺省的处理程序。我使用 $ 来代表被抛出的异常对象。如果没有指定 $error 从句,就将打印出一个合理的出错信息(很可能是堆栈跟踪信息)。
注意,为确保线程安全,异步方法的参数必须是不变 (immutable) 的。运行时系统应通过相关语义来保证这种不变性(简单的复制通常是不够的)。
所有的 task 对象必须支持一些伪信息 (pseudo-message)。
除了常用的修饰符(public 等), task 关键字还应接受一个 $pooled(n) 修饰符,它导致 task 使用一个线程池,而不是使用单个线程来运行异步请求。 n 指定了所需线程池的大小;必要时,此线程池可以增加,但是当不再需要线程时,它应该缩到原来的大小。伪域 (pseudo-field) $pool_size 返回在 $pooled(n) 中指定的原始 n 参数值。
在《Taming Java Threads 》的第八章中,我给出了一个服务器端的 socket 处理程序,作为线程池的例子。它是关于使用线程池的任务的一个好例子。其基本思路是产生一个独立对象,它的任务是监控一个服务器端的 socket。每当一个客户机连接到服务器时,服务器端的对象会从池中抓取一个预先创建的睡眠线程,并把此线程设置为服务于客户端连接。socket 服务器会产出一个额外的客户服务线程,但是当连接关闭时,这些额外的线程将被删除。
Socket_server对象使用一个独立的后台线程处理异步的 listen() 请求,它封装 socket 的“接受”循环。当每个客户端连接时, listen() 请求一个 Client_handler 通过调用 handle() 来处理请求。每个 handle() 请求在它们自己的线程中执行(因为这是一个 $pooled 任务)。
注意,每个传送到$pooled $task 的异步消息实际上都使用它们自己的线程来处理。典型情况下,由于一个 $pooled $task 用于实现一个自主操作;所以对于解决与访问状态变量有关的潜在的同步问题,最好的解决方法是在 $asynchronous 方法中使用 this 是指向的对象的一个独有副本。这就是说,当向一个 $pooled $task 发送一个异步请求时,将执行一个 clone() 操作,并且此方法的 this 指针会指向此克隆对象。线程之间的通信可通过对 static 区的同步访问实现。

1 前言在发布DALL·E的15个月后,OpenAI在今年春天带了续作DALL·E 2,以其更加惊艳的效果和丰富的可玩性迅速占领了各大AI社区的头条。近年来,随着生成对抗网络(GAN)、变分自编码器(VAE)、扩散模型(Diffusion models)的出现,深度学习已向世人展现其强大的图像生成能力;加上GPT-3、BERT等NLP模型的成功,人类正逐步打破文本和图像的信息界限。在DALL·E 2中,只需输入简单的文本(prompt),它就可以生成多张1024*1024的高清图像。这些图像甚至

“Making large models smaller”这是很多语言模型研究人员的学术追求,针对大模型昂贵的环境和训练成本,陈丹琦在智源大会青源学术年会上做了题为“Making large models smaller”的特邀报告。报告中重点提及了基于记忆增强的TRIME算法和基于粗细粒度联合剪枝和逐层蒸馏的CofiPruning算法。前者能够在不改变模型结构的基础上兼顾语言模型困惑度和检索速度方面的优势;而后者可以在保证下游任务准确度的同时实现更快的处理速度,具有更小的模型结构。陈丹琦 普

Wav2vec 2.0 [1],HuBERT [2] 和 WavLM [3] 等语音预训练模型,通过在多达上万小时的无标注语音数据(如 Libri-light )上的自监督学习,显著提升了自动语音识别(Automatic Speech Recognition, ASR),语音合成(Text-to-speech, TTS)和语音转换(Voice Conversation,VC)等语音下游任务的性能。然而这些模型都没有公开的中文版本,不便于应用在中文语音研究场景。 WenetSpeech [4] 是

由于复杂的注意力机制和模型设计,大多数现有的视觉 Transformer(ViT)在现实的工业部署场景中不能像卷积神经网络(CNN)那样高效地执行。这就带来了一个问题:视觉神经网络能否像 CNN 一样快速推断并像 ViT 一样强大?近期一些工作试图设计 CNN-Transformer 混合架构来解决这个问题,但这些工作的整体性能远不能令人满意。基于此,来自字节跳动的研究者提出了一种能在现实工业场景中有效部署的下一代视觉 Transformer——Next-ViT。从延迟 / 准确性权衡的角度看,

3月27号,Stability AI的创始人兼首席执行官Emad Mostaque在一条推文中宣布,Stable Diffusion XL 现已可用于公开测试。以下是一些事项:“XL”不是这个新的AI模型的官方名称。一旦发布稳定性AI公司的官方公告,名称将会更改。与先前版本相比,图像质量有所提高与先前版本相比,图像生成速度大大加快。示例图像让我们看看新旧AI模型在结果上的差异。Prompt: Luxury sports car with aerodynamic curves, shot in a

译者 | 李睿审校 | 孙淑娟近年来, Transformer 机器学习模型已经成为深度学习和深度神经网络技术进步的主要亮点之一。它主要用于自然语言处理中的高级应用。谷歌正在使用它来增强其搜索引擎结果。OpenAI 使用 Transformer 创建了著名的 GPT-2和 GPT-3模型。自从2017年首次亮相以来,Transformer 架构不断发展并扩展到多种不同的变体,从语言任务扩展到其他领域。它们已被用于时间序列预测。它们是 DeepMind 的蛋白质结构预测模型 AlphaFold

JavaScript中void运算符存在意外行为和干扰类型推断的缺陷。替代解决方案包括:1.使用undefined明确表达意图;2.使用null表示不存在值;3.使用三元运算符简明指定不同情况的值。

探析SessionStorage的限制与缺陷SessionStorage是一种在客户端存储数据的机制,它提供了一种在同一浏览器会话中存储键值对的方式。每个存储项与浏览器窗口或标签页相关联,并在该会话期间持续保存。虽然SessionStorage在某些方面提供了一些便利,但它也存在一些限制和缺陷,本文将逐一讨论这些问题,并提供具体的代码示例。数据容量限制Ses


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SecList
SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

ZendStudio 13.5.1 맥
강력한 PHP 통합 개발 환경

에디트플러스 중국어 크랙 버전
작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음
