爪哇:线程技术和概念
-
07-07-2019 - |
题
当使用线程时,我有时将它们想象为将空间上下文中的对象之间的 3 维或更多维互连编织在一起。这不是一般的用例场景,但对于我所做的事情来说,这是一种有用的思考方式。
您是否使用任何 API 来辅助线程?
您是否以一种不将线程概念化为进程的方式使用线程?
解决方案
您使用哪些API辅助线程化?
你的意思是来自 java.util.concurrent
的appart? FunctionalJava 获得了一些有助于并发编程的构造,如启动此处。
您是否以一种不将线程视为流程的方式使用线程?
是的,就线程根本没有概念化而言。以异步任务运行器为例。它使用了封面下的线程,但我没有看到它们,我也不关心它们。它们完全由任务运行员管理。
在幕后,它只是线程,但是当我们停止关注单个线程时,只需将它们视为多个插槽,您可以以某种方式放入代码并使其运行一段时间,然后那时我们开始达到更高的抽象水平。
代理/演员是执行此操作的常用方法。一个Actor就像一个有一个状态块的线程,然后你可以发送一些代码,然后在你有时间的时候说“对你的状态这么做”。或类似的东西。
其他提示
首先
通常的免责声明:使用任何语言、使用任何抽象级别的并发编程是 难的 和 复杂的 并且存在很多风险。考虑到:
- 并发编程使任何应用程序变得非常复杂
- 对关键部分进行单元测试很困难,有时甚至是不可能的
- 重现源自并发代码的错误是 很难 并且很大程度上取决于架构、操作系统风格、版本等......
Java 并发 API
Java 在使并发编程对开发人员来说尽可能简单方面已经取得了长足的进步。对于大多数情况,您会看到 java.util.concurrent
拥有您需要的大部分抽象:
Runnable
接口和Thread
您可以扩展的对象。只需输入您的代码,您就有一个可以运行的线程了- 一套不错的
Executors
: :常量池、动态池、计划池或其他。只需扔一个Runnable
它会完成剩下的工作。 Semaphore
s 和 锁 各种各样的功能使您无需实施常见的锁定技术。- 内置一个
wait()
和notify()
所有对象的 API。
用途
作为软件工程师,你唯一要做的就是确保你正在编写 正确的 代码。这意味着您应该意识到您可能面临的危险情况:
- 僵局 - 两个或多个线程正在等待无序资源的情况,从而呈现无限等待循环。
- 活锁 - 两个或多个线程礼貌地尝试在共享资源上让路给另一个线程,但最终没有接受它(考虑走廊里的两个人互相走来,并不断地一起从一边移动到另一边)
- 饥饿 - 单个线程占用大部分或全部单个共享资源,从而剥夺其他线程对其的访问。
要点(或者何时使用)
仅当并发性将直接改善应用程序行为时才使用线程。
如果您正在等待 IO/网络/硬件绑定资源, 做 在其上生成一个线程,以便您可以继续做其他事情。
如果您只是想优雅地拆分 CPU 密集型计算, 不要 使用线程。你最终可能会恶化你的表现。
如果您确实使用线程,请确保您已经彻底考虑了风险,并仔细检查了您没有错过任何异常情况。
有用的(在线)资源
进入事物的最快方法是 Sun 并发教程. 。除此之外,买一本好书。
祝你好运 :)
并发是一个深层而复杂的话题。 Java Concurrency in Practice 等书籍可能会有所帮助。
请参阅并发实用程序概述线程上的API。 BlockingQueue< E> 可以是有用的。例如。
另外支持的队列 等待队列的操作 检索时变为非空 元素,并等待空间成为 存储时可在队列中使用 元件。
请参阅 CountDownLatch
允许一个同步辅助工具 或更多线程等待一组 在其他地方执行的操作 线程完成。
和 CyclicBarrier 对于一些有趣的行为。
允许a的同步辅助 一组线程都等待每一个 另一个是达到共同的障碍点。
修改强>: 我正在阅读Java Concurrency in Practice。这非常好。
当使用线程时,我有时将它们可视化为将空间上下文中的对象之间的三维或更多维互连编织在一起。
这听起来很复杂,你会如何构思600线程?为什么不将它们视为同时运行的多个执行线程。
您使用哪些API辅助线程化?
我建议最简单,最直接的是你会发现的第一场比赛。 http://www.google.co.uk/search?q=java+线程
您是否以一种不将线程概念化为进程的方式使用线程?
由于线程不是进程,我不能说我曾经想过线程作为进程。 (旧版Linux除外)进程默认情况下不共享内存/对象,它们完全独立运行(通常是不同的程序,可能用不同的语言编写)。使用不同的API也会以不同的方式启动它们。
有一种观点认为多线程很复杂。其实我会说相反的。多线程编程要求您使代码简单,易于理解并直接推理。虽然这需要经验,但您的目标是简单。