【问题标题】:where can I find java thread safe objects concept description?我在哪里可以找到 java 线程安全对象的概念描述?
【发布时间】:2015-12-31 20:44:08
【问题描述】:

我经常听说 Java 应用程序结构创建的现代概念之一是有效的线程安全对象概念。这意味着我们只在我们的应用程序中使用最终实体类。我在哪里可以找到该概念的综合指南?如何使用 DAO 和 DTO 方法将这个概念应用于基于 hibernate 和 spring 的普通 MVC Web 应用程序?

【问题讨论】:

  • 寻找不可变对象
  • ...最终实体类...,没有意义。 final 类可能无法扩展,但我认为您在谈论的是 immutable 类(即,只有最终 fields 的类) .不可变类本质上是线程安全的,因为在实例完全构造之前无法在线程之间共享它的实例,并且在构造实例之后无法修改实例. “线程安全”就是管理共享的、可变的状态。如果一个对象是不可变的,那么共享时就不存在“线程安全”问题。
  • 我在哪里可以找到综合指南...? 如果您还没有学习过 Java 并发教程,那将是一个很好的起点:docs.oracle.com/javase/tutorial/essential/concurrency

标签: java multithreading spring hibernate


【解决方案1】:

你的问题很广泛。

您可以从 https://en.wikipedia.org/wiki/Thread_safety 开始,这只是漫长旅程的开始,您将通过 http://www.cs.umd.edu/~pugh/java/memoryModel/ 了解 Java 内部结构,然后再了解现代 CPU 内部结构。

这件事的背后是以下事情:

  • state - 某个值等于某个“X”,例如姓名 John
  • 可变状态 - 某个值是 John,现在应该是 Donald
  • 执行流程 - 一个接一个执行的程序步骤序列
  • 线程 - 流的执行者
  • 多线程 - 您的代码有多个并行执行的流程

(例如,一个网络查询请求 GET person 通过它的 id=8374 和其他请求 GET all people 以获取所有已知用户)

可能出什么问题 - 一个调用返回用户是 Donald,并列出所有用户返回他是 John(从其他线程观察到陈旧值)。

同样的问题可能发生在“较低级别”——例如,一个线程更改了 counter = counter + 1,而其他线程也在做同样的事情。如果一切正常且计数器的起始值 = 3,则第一个将取 3,加 1,并设置计数器 = 4。然后第二个将来,将取 4,加 1,并将计数器设置为 5。

如果出现问题,您可能会遇到这样的情况,即 1st 会将计数器的值设为 3,将值存入内存并会因内部问题暂停片刻。在那一刻,第二个将观察到计数器为 3 并将其放入内存中,将进行数学运算并存储计数器 = 4。第一个将恢复执行,将执行 3 + 1(无需从计数器重新读取值)并将做商店 4 来柜台。结果 - 你“失去”了一个增量。

Web 级别、Java 级别、CPU 级别存在相同的问题。

解决此问题的主要方向:

“不变性” - 值被分配一次并且之后永远不会改变的概念 - 可以尝试通过对变量使用 final 来实现。

“同步” - 您可以使用 synchronize 关键字将代码的某些部分标记为仅作为一个原子操作执行,而不会被其他线程交错(第二个线程将等待第一个线程完成所有步骤)。

等等。这确实是计算机科学的一大领域。请转到前面提到的 wiki 页面。

在 spring/hibernate 的情况下 - 你不能让所有东西都不可变,所以你将创建改变状态的代码,以便使用同步块在单线程中执行。可能在 java 代码中,也可能在 db 代码中。

【讨论】:

    猜你喜欢
    • 2017-12-12
    • 1970-01-01
    • 1970-01-01
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    相关资源
    最近更新 更多