`

多线程的困惑

 
阅读更多
多线程的困惑

转自:http://www.ibm.com/developerworks/cn/java/j-lo-spring-ts1/index.html

由于 Spring 的事务管理器是通过线程相关的 ThreadLocal 来保存数据访问基础设施,再结合 IOC 和 AOP 实现高级声明式事务的功能,所以 Spring 的事务天然地和线程有着千丝万缕的联系。

我们知道 Web 容器本身就是多线程的,Web 容器为一个 Http 请求创建一个独立的线程,所以由此请求所牵涉到的 Spring 容器中的 Bean 也是运行于多线程的环境下。在绝大多数情况下,Spring 的 Bean 都是单实例的(singleton),单实例 Bean 的最大的好处是线程无关性,不存在多线程并发访问的问题,也即是线程安全的。
一个类能够以单实例的方式运行的前提是“无状态”:即一个类不能拥有状态化的成员变量。我们知道,在传统的编程中,DAO 必须执有一个 Connection,而 Connection 即是状态化的对象。所以传统的 DAO 不能做成单实例的,每次要用时都必须 new 一个新的实例。传统的 Service 由于将有状态的 DAO 作为成员变量,所以传统的 Service 本身也是有状态的。

但是在 Spring 中,DAO 和 Service 都以单实例的方式存在。Spring 是通过 ThreadLocal 将有状态的变量(如 Connection 等)本地线程化,达到另一个层面上的“线程无关”,从而实现线程安全。Spring 不遗余力地将状态化的对象无状态化,就是要达到单实例化 Bean 的目的。
由于 Spring 已经通过 ThreadLocal 的设施将 Bean 无状态化,所以 Spring 中单实例 Bean 对线程安全问题拥有了一种天生的免疫能力。不但单实例的 Service 可以成功运行于多线程环境中,Service 本身还可以自由地启动独立线程以执行其它的 Service。下面,通过一个实例对此进行描述:

在 ① 处,在主线程(main)执行的 UserService#logon() 方法的事务启动,在 ③ 处,其对应的事务提交,而在子线程(Thread-2)执行的 ScoreService#addScore() 方法的事务在 ② 处启动,在 ④ 处对应的事务提交。
所以,我们可以得出这样的结论:在 相同线程中进行相互嵌套调用的事务方法工作于相同的事务中。如果这些相互嵌套调用的方法工作在不同的线程中,不同线程下的事务方法工作在独立的事务中。

在本文中,我们通过剖析了解到以下的真相:
在没有事务管理的情况下,DAO 照样可以顺利进行数据操作;
将应用分成 Web,Service 及 DAO 层只是一种参考的开发模式,并非是事务管理工作的前提条件;
Spring 通过事务传播机制可以很好地应对事务方法嵌套调用的情况,开发者无须为了事务管理而刻意改变服务方法的设计;
由于单实例的对象不存在线程安全问题,所以进行事务管理增强的 Bean 可以很好地工作在多线程环境下。
分享到:
评论

相关推荐

    C#进度条(多线程+委托)新手教学

    在本文中,我们将深入探讨如何使用C#实现一个进度条,并结合多线程和委托技术来提高程序的执行效率和用户体验。首先,我们要明白进度条的基本原理:进度条通常与后台任务关联,通过更新进度值来反映任务的完成情况。...

    异步/多线程/任务/并行编程之一:如何选择合适的多线程模型?

    然而,多种多线程模型的存在可能会让开发者感到困惑。知名专家Jeffrey Richter曾表示这是微软的一个遗憾,因为它可能导致开发者的混乱。尽管如此,随着技术的发展,C#的语法特性已经变得更为强大,适应了不断变化的...

    IOS编程中使用多线程

    ### IOS编程中使用多线程 #### 背景与问题描述 在iOS应用开发过程中,经常遇到的一个问题是:应用程序加载数据时导致UI界面卡顿甚至假死,从而严重影响用户体验。例如,当从网络或者本地数据库加载大量数据时,...

    .Net线程示例

    然而,由于 .Net 提供了多种多样的多线程工具和技术,初学者往往会感到困惑,不知道如何选择最适合自己的场景的技术。本文将重点介绍使用 .Net 的 `Thread` 类进行多线程编程的基本方法,并通过一个具体的 C# 示例来...

    JavaScript是否可实现多线程 深入理解JavaScript定时机制

    然而,这并不意味着JavaScript无法处理异步操作或者模拟多线程的行为。JavaScript通过事件循环(Event Loop)和异步任务队列来实现这一点,使得它可以处理网络请求、定时器以及其他I/O操作,而不会阻塞主线程。 ...

    易语言-易语言多线程adsl宽带拨号

    在描述中提到,有些易语言开发者可能对如何在多线程环境下进行拨号操作感到困惑,担心拨号过程会干扰到其他线程。解决这个问题的关键在于正确地管理和同步线程。一种常见的方法是使用线程同步机制,如互斥量、信号量...

    基于线程与分布式排序对比实验的设计与研究.pdf

    本篇研究论文探讨了单线程、多线程以及分布式环境下排序算法的性能,以及它们在执行流程、算法代价和适用场景方面的对比,并提出了在分布式环境下采用多线程解决海量数据排序问题的方案。 首先,我们需要了解单机单...

    Java线程问题代码

    从给定的文件标题“Java线程问题代码”和描述“Java线程问题代码详细解读,希望对各位有用处”,我们可以看出,这份代码是关于Java多线程编程的一个实例,旨在展示线程创建、运行以及线程间通信的一些基本概念和潜在...

    BackgroundWoker类解决软件界面卡死问题

    为了解决这个问题,多线程编程成为了一个重要的工具。在Windows窗体(WinForms)应用程序中,Microsoft为开发者提供了一个方便的类,即BackgroundWorker类,来帮助解决界面卡死问题。 首先,让我们讨论一下...

    JavaScript可否多线程? 深入理解JavaScript定时机制

    在探讨JavaScript是否支持多线程之前,我们需要先了解JavaScript的基本运行机制。JavaScript作为一种轻量级脚本语言,其主要用途在于增强用户界面的交互性和动态效果。但是,谈到多线程,JavaScript引擎实际上是单...

    Java理论与实践:描绘线程安全性

    Java中的线程安全性是并发编程中的关键概念,它关乎到多线程环境下程序的稳定性和正确性。线程安全的类意味着在多个线程并行访问时,它们的行为仍然是正确和一致的,无需额外的同步措施。然而,线程安全并不简单地...

    Python实现的多线程端口扫描工具分享

    昨晚今晚写了两晚,总算把Py Port Scanner 写完了,姑且称之为0.1版本,算是一个Python多线程端口扫描工具。 水平有限,实话中间有一些困惑和不解的地方,代码可能也写的比较乱。有些问题并未找到很好的解决方法,还...

    Java编程思想让很多新手止步不前,困惑已久的问题由此解开

    线程是程序执行的独立路径,理解线程间的同步和通信机制,如synchronized关键字、wait()、notify()方法,能够帮助开发者编写高效的多线程程序,应对现代计算环境的复杂需求。 总的来说,Java编程思想虽然初学时可能...

    Java线程 详解

    正确地理解和使用线程对于开发高效、稳定的多线程应用程序至关重要。本文档通过详细介绍线程的基础知识、生命周期、同步机制以及线程池等内容,希望能够帮助读者建立起对Java线程的全面认识,并在实际开发中灵活运用...

    NC65进度条功能.rar

    1. **多线程编程**:为了不影响用户界面的响应,进度条更新通常会在后台线程进行,主界面线程则负责显示进度。这需要对.NET的并发和多线程模型有深入理解。 2. **事件驱动编程**:进度条的更新可能依赖于数据导入...

    java线程入门教程,涉及线程基本知识,显浅易懂..zip

    Java线程是多任务编程的重要概念,特别是在Java这种支持并发执行的编程语言中。线程允许程序同时执行多个独立的任务,极大地...通过学习这个教程,你将能够掌握Java线程的基本操作,为后续的多线程编程打下坚实的基础。

    Java六大关键是什么你知道吗

    虽然多线程编程可以被视为一种逻辑能力的挑战,但在很多应用场景中,实际上并不需要编写多线程程序。因为在现代平台中,多线程机制已经被内置。对于开发者而言,更重要的是理解多线程的基本原理和如何确保多线程的...

    菜鸟入门:Java语言学习六大要点(辅你成凤)

    虽然多线程编程对一些程序员来说是一种逻辑上的挑战,但在大多数应用场景下,多线程机制已内置到基础平台中,无需程序员手动编写多线程代码。然而,理解多线程原理和确保多线程安全对编写准确无误的程序至关重要。...

    多核 编程 技术 指南

    本文将深入探讨多线程、多进程、并行计算的概念,以及如何在实际开发中利用它们优化程序性能。 一、多核编程基础 1. 并行与并发:并行处理是指多个任务在同一时刻同时进行,而并发则是在一段时间内交替执行多个任务...

    gif动画等待线程.rar_等待 动画

    线程在多任务处理中扮演着关键角色,它可以让你的程序同时执行多个操作。在这个上下文中,"等待线程"是指一个独立运行的线程,它的任务是显示GIF动画,告知用户程序正在后台执行任务。当主线程执行耗时操作时,等待...

Global site tag (gtag.js) - Google Analytics