读完了《Java并发编程实践》这本书以后,以为对一般的线程安全问题有一个大概的理解,但是今天遇到的这个问题着实非常神奇,在书中也没有被提到过,这里特别记录下来。
public class Test {
public void test1(O o) throws Exception {
System.out.println("begin o:" + o.getId() + " " + o.getName());
if (o.getId() == 1) {
Thread.sleep(10000);
System.out.println("o1:" + o.getId() + " " + o.getName());
}
if (o.getId() == 2) {
System.out.println("o2:" + o.getId() + " " + o.getName());
}
System.out.println("end o:" + o.getId() + " " + o.getName());
}
public static void main(String[] args) throws Exception {
final O o1 = new O(1, "o1");
Thread t1 = new Thread() {
@Override
public void run() {
try {
Test test = new Test();
test.test1(o1);
} catch (Exception e) {
e.printStackTrace();
}
}
};
Thread t2 = new Thread() {
@Override
public void run() {
try {
o1.setId(2);
o1.setName("o2");
Test test = new Test();
test.test1(o1);
} catch (Exception e) {
e.printStackTrace();
}
}
};
t1.start();
Thread.sleep(10);
t2.start();
}
}
class O {
public O(int id, String name) {
super();
this.id = id;
this.name = name;
}
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
两个线程先后启动,传入的是不同状态的同一对象。在test1方法的第一条打印中可以看出来,参数对象的状态是不同的,但是当第一个线程在第一个判断处休眠第二个线程开始执行以后,第一个线程打印出来的状态就和之前不一致了,其状态和第二个参数对象的状态一样。按照理论,方法执行以后,JVM会在独立的线程中压入一个方法栈,栈中会包含一个方法执行所需要的所有元素(包括代码和参数),这里为什么会出现方法执行到一半的时候参数状态改变呢?
推测:因为方法栈中压入的是一个对象的指针,而不是整个对象,所有当对象的状态被改变的时候还是可以第一时间被独立线程所察觉,所以尽管已经进入了方法栈,还是会引起对象状态的改变。
以后在处理多线程的问题时,必须要所用无状态Immutable的VO对象。这样才能保证线程安全
分享到:
相关推荐
servlet线程安全问题servlet线程安全问题
HashMap为什么是线程不安全的?如何解决HashMap的线程不安全问题?
内容概要:文章内容从原子性、可见性、有序性三个方面介绍C++线程安全问题的原因。通过原子操作、线程同步如互斥锁、读写锁、条件变量、信号量等方法解决C++线程安全问题。同时介绍了线程安全的单例,饿汉模式和懒汉...
栈的线程安全问题 的解决代码 push pop synchronized THread
ProC 线程安全问题案例,多线程proc开发简单介绍
servlet与Struts action线程安全问题分析
高级程序员必会的HashMap的线程安全问题,适用于0~2年的
下面小编就为大家分享一篇浅谈C#跨线程调用窗体控件(比如TextBox)引发的线程安全问题,具有很好的参考价值,希望对大家有所帮助
深入研究Servlet线程安全性问题...
解决利用timer循环扫描导致的控件跨界问题,以及控件被多线程占用问题,本人资源全部免费,有需要的朋友直接下载吧
最近在做多线程方面的工作,工作中发现多线程中很多坑,这里就有一个List添加对象的误区,解释了List容量扩展后内存开辟导致的线程不安全性的问题,这里做个分享跟大家讲讲这个坑是怎么形成的怎么样避免。
其实java的多线程并发问题最终都会反映在java的内存模型上,所谓线程安全无非是要控制多个线程对某个资源的有序访问或修改。总结java的内存模型,要解决两个主要的问题:可见性和有序性。我们都知道计算机有高速缓存...
java ,线程通信安全问题 ,属于入门代码,简单。 不喜勿喷呀。
什么是线程安全? 答:线程安全是多线程编程时的计算机程序代码中的一个概念。在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等...
c++ stl线程安全 c++ stl线程安全 c++ stl线程安全
你还在用synchronized?线程安全相关知识深入剖析
Delphi多线程的安全问题分析及解决,实现多线程的安全
Java多线程--线程安全问题练习题
C++线程安全日志库-Win32接口实现,博客讲解:https://www.cnblogs.com/swarmbees/ ->C++线程安全日志库-Win32接口实现
struts1,struts2,webwork,线程安全问题,easy518网 http://www.easy518.com/