`
cantellow
  • 浏览: 847361 次
  • 性别: Icon_minigender_1
  • 来自: 草帽海贼团
社区版块
存档分类
最新评论

无状态类在并发环境中绝对安全吗?

阅读更多

无状态类是指一个对象没有任何属性,就像下面这个类一样,通常来说无状态的类在并发环境中比较安全:

 

class Class1 {
    public void doSomeThing() {
	Vector<String> vector = new Vector<String>();
	String element = "";
	if (!vector.contains(element)) {
	    vector.add(element);
	}
    }    
}

 

 doSomeThing方法执行过程在JVM中表示为:


这样看起来,即使对象Vector1和对象Vector2保存在堆上对所有栈可见,但是能够访问它们的引用局限在栈中,所以栈1只能访问Vector1,栈2只能访问Vector2,而且当方法执行完毕,对象Vector1和对象Vector2很快失去“重力”,被垃圾回收掉。

 

但是,有没有这样一种可能,在doSomeThing方法的执行过程中,两个Vector引用指向同一个Vector对象,那么这时候,就有可能出现问题,为了达到这个目的,

看下面的程序:

 

public class Class2 {
  private static Vector<String> vector = new Vector<String>();
  public Vector<String> getVector() {
	return vector;
    }

  public static void main(String[] args) {
	Class3 c = new Class3();
	Thread t = new Thread(new Runnable() {
	    public void run() {
		Class3 c = new Class3();
		c.doSomeThing();
	    }
	});
	t.start();
	c.doSomeThing();
	System.out.println(vector);
    }
}
 

 

class Class3 {
    public void doSomeThing() {
	Vector<String> vector;
	Class2 c = new Class2();
	vector = c.getVector();
	String element = "cantellow";
	if (!vector.contains(element)) {//在此处打上断点
	    vector.add(element);
	}
    }
}

 用eclipse在if (!vector.contains(element))打上断点,

然后让main线程和thread0线程交替执行,最后输出结果为:[cantellow, cantellow]

虽然正常run程序的话,只输出[cantellow],但是不排除上面的可能,特别是在大型应用程序中。

所以,无状态的类在并发情况中不能说是绝对安全的,一般静态变量对象是很容易被共享出来的,即使这个静态变量本身是线程安全的(vector),也不能保证它被多个栈引用时能确保正确的行为。

对于有状态的类我们很谨慎,因为有状态就意味着对象中的方法能够任意访问它,对于无状态的类来说,我们也需要谨慎对待,因为无状态类的方法很可能获取堆上其他已存在对象的引用,而不是重新生成对象,当这个对象是唯一的时候(静态变量很容易做到这一点),如果我们不对此方法进行同步或者协调,那么很可能,就会出现并发问题。

同样的道理,你也不能说不可变类在并发环境中是安全的。

  • 大小: 36.1 KB
3
1
分享到:
评论
7 楼 cantellow 2011-04-02  
isaac.198 写道
Class2  已经有状态了,因为你定义一个域,也就是类变量...
所以无状态的类是安全的

大哥,我说的是Class3 
6 楼 isaac.198 2011-04-02  
Class2  已经有状态了,因为你定义一个域,也就是类变量...
所以无状态的类是安全的
5 楼 cantellow 2011-04-02  
hsiss 写道
静态成员相当于全局变量,使用了全局变量的服务就不能被称为无状态的了
这个类不能算是无状态类
spring搞那么复杂无非是想去掉和全局变量类似的所有元素
只有遵循函数式的写法才能保证服务时无状态的

嗯,这位兄台说的有道理,看起来我文中的例子还不是绝对的无状态,但是只要两个栈的引用指向同一个对象就有可能发生这种可能,不一定是静态变量。
4 楼 hsiss 2011-04-01  
静态成员相当于全局变量,使用了全局变量的服务就不能被称为无状态的了
这个类不能算是无状态类
spring搞那么复杂无非是想去掉和全局变量类似的所有元素
只有遵循函数式的写法才能保证服务时无状态的
3 楼 cantellow 2011-03-31  
hsiss 写道
这样写也可以,用实例方法返回静态成员

你是疑问语气还是肯定语气?
如果是疑问语气的话,当然可以了。
只不过我这里好像多次一举了,直接将getVector方法写成静态的,不用生成Class1实例,但是效果都一样,对这篇文章的主题是没有任何影响的。
2 楼 hsiss 2011-03-31  
这样写也可以,用实例方法返回静态成员
1 楼 hsiss 2011-03-31  
# public class Class2 { 
#   private static Vector<String> vector = new Vector<String>(); 
#   public Vector<String> getVector() { 
#     return vector; 
#     } 

相关推荐

    线程安全Vector

    2. **完全线程安全**:类中的所有方法都是线程安全的,可以在多线程环境中自由使用。 3. **有条件线程安全**:部分方法线程安全,部分方法需要外部同步才能保证线程安全。 4. **线程兼容**:需要外部同步才能在多...

    UNIX-编程中错误输出的线程安全问题.pdf

    为了避免这类问题,开发者需要考虑使用线程安全的替代方案,如使用带 `_r` 后缀的函数,或者自定义错误处理机制,确保在并发执行时不会引发数据竞争。 总的来说,多线程环境下的错误输出处理是UNIX编程中的一个重要...

    呼吸内科并发症.doc

    【呼吸内科并发症】是呼吸系统疾病患者在治疗过程中可能遇到的严重问题,这些并发症包括肺炎的并发症如肺脓肿、呼吸衰竭、败血症、感染性休克等,以及支气管扩张症可能导致的大咯血和窒息。针对这些并发症,医护人员...

    3第三章知识点整理2

    2. 绝对线程安全:非常罕见,即使在并发环境下,对象在任何时刻都能提供正确结果,Java API中大多数标注为线程安全的类并不属于这一类。 3. 相对线程安全:对象自身是线程安全的,但某些特定连续调用可能需要额外的...

    java多线程设计

    不可变对象在多线程环境中具有天然的安全性,因为它们的值不会在并发访问时被意外修改。这使得多个线程可以共享一个不可变对象,无需担心数据一致性问题,从而提高了程序的并发性能。 三、Java多线程防止非安全问题...

    安全编程技术

    1. **任何软件都不可能是绝对安全的**:无论软件设计多么严谨,都可能存在漏洞。例如,网络软件可能会被黑客利用其缺陷进行攻击。 - **提示**:网络软件面临的风险包括未经授权的访问和利用软件缺陷进行控制或...

    2022年Java服务器端编程安全必读Java教程.docx

    \n\n**三、竞争状态(Race Condition)**\n\n竞争状态是指在并发环境下,多个线程同时访问共享资源时可能导致的不确定行为。Java通过同步机制,如`synchronized`关键字,来确保在多线程环境中的数据一致性,防止竞争...

    JAVA 线程类应用

    在实际开发中,还需要考虑线程安全的数据结构、死锁问题、线程局部变量(ThreadLocal)以及Callable和Future接口,这些都是Java线程类应用中常见的知识点。 总之,Java线程类应用涉及的内容广泛,包括线程的创建与...

    小学生暑假安全教育剖析PPT学习教案.pptx

    中暑是由于长时间暴露在高温环境中,体温调节失常导致的一种病理状态。中暑症状包括头痛、恶心、眩晕、皮肤干燥和热射病等。预防中暑的关键是避免过度暴露在炎热环境下,及时补充水分和电解质。 游泳是夏季常见的...

    ejb3.0培训教程与源码(绝对精品)

    1, 服务器端的一个组件模型,能部署在多层环境中; EJB API, javax.ejb.*; 2, EJB容器可以为我们提供中间件服务; 3, EJB客户端:(常见的) 1) 独立的java程序 2)web程序 3)其他的EJB, 4)其他通过Web Service ...

    hibernate乐观锁和悲观锁学习

    悲观锁正如其名字所示,假设并发环境中数据会被频繁修改,所以在整个数据处理过程中,它会保持数据锁定状态。这样可以防止其他事务在同一时间内对数据进行修改。在数据库层面,悲观锁通常通过`SELECT ... FOR UPDATE...

    15道面试常问的Java多线程面试题!.zip

    Java多线程是Java编程中的核心概念,尤其在并发编程领域有着至关重要的地位。下面将详细解析这15道常见的Java多线程面试题,帮助你深入理解和掌握相关知识点。 1. **线程的创建方式** - 实现Runnable接口:创建一...

    百度HI源码 绝对可用

    2. 高并发处理:在大规模用户环境下,数据库需要应对高并发读写。源码中可能包含了数据库连接池、读写分离、缓存策略等优化手段。 3. 数据一致性:通过ACID(原子性、一致性、隔离性、持久性)原则保证数据的一致性...

    thread.zip

    10. **线程安全**:线程安全的类或方法是保证在多线程环境中正确工作的方法。例如,`Collections.synchronizedXXX`方法用于创建线程安全的集合。 通过"thread.zip"中的示例代码,你可以学习如何在实际项目中应用...

    QA签到系统绝对可用

    描述中的重复文字“签到系统绝对可用”进一步强调了系统的稳定性和可靠性,这在任何业务环境中都是至关重要的。一个绝对可用的签到系统意味着它能够持续运行,不受常见故障的影响,同时提供实时或近实时的签到数据。...

    javathread.part104.rar

    10. **并发集合类**:Java提供了一系列并发安全的集合类,如`ConcurrentHashMap`、`CopyOnWriteArrayList`等,它们在多线程环境下提供高效且安全的数据访问。 11. **Future和Callable接口**:这两个接口与`...

    线程方法操作

    线程安全的类或方法能够在多线程环境下正确工作,不会因为线程间的交互导致错误。例如`Atomic`类提供原子操作,`Collections.synchronizedXXX`方法返回线程安全的集合。 9. **中断线程** 通过`interrupt()`方法...

    完整word版-安工大操作系统期末考试绝对重点已经考完检验过.doc

    死锁和饥饿是并发环境下可能出现的问题。死锁是当一组进程相互等待对方释放资源而陷入无法继续执行的状态,而饥饿则是指一个进程因为优先级低而被无限期推迟执行。避免死锁需要满足不剥夺、互斥、占有并等待和循环...

    绝对价值不菲的对战平台源代码

    这类平台通常包含了用户管理、房间创建、匹配系统、聊天功能、计分板以及游戏状态同步等多种复杂功能。"绝对价值不菲的对战平台源代码" 提供的可能是一个完整的、具有商业级别的对战平台开发基础,对于开发者而言,...

    操作系统复习题及参考答案专科.doc

    13. 预防死锁是指在资源动态分配过程中,用某种方法去防止系统进入不安全状态。预防死锁可以通过银行家算法、资源 ordering 等方法来实现。 14. 死锁与程序的死循环一样。死锁是指两个或多个进程在等待资源.release...

Global site tag (gtag.js) - Google Analytics