理解线程安全

     这礼拜被人问到2次关于action是否是线程安全的?论坛也时常看到有关于线程安全是什么的提问。线程安全到底是什么。现在谈安全,那就是说本来的是不安全的。所以觉得应该转换下问题变成什么是线程不安全。
 
     自己写了个例子,很多线程同时访问一个对象。
 
测试结果如下
 
instanceVar是Thread-0 localVar是Thread-0等待...
instanceVar是Thread-1 localVar是Thread-1等待...
等待结束 instanceVar是Thread-1 localVar是Thread-0
等待结束 instanceVar是Thread-1 localVar是Thread-1
 
 
从结果的第3行可以看到局部变量是Thread-0,最后类成员却变成Thread-1
 
得到一个结论:
对象方法中局部变量是在单个线程的工作内存中操作,不共享。
对象成员存在于公共内存中,和所有线程共享。
所以对象成员有可能不会出现本来预想中的值,也就称之为“ 线程不安全”。
 

 
那么具体发生错误的经过是怎么样的呢,为什么要加一句Thread.sleep(1)。
 
如果 注释Thread.sleep(1),那把循环数加到到50。会得到下面的结果
 
测试结果如下:(太长,只区的局部片断)
instanceVar是Thread-0 localVar是Thread-0等待...
等待结束 instanceVar是Thread-0 localVar是Thread-0
instanceVar是Thread-1 localVar是Thread-1等待...
等待结束 instanceVar是Thread-1 localVar是Thread-1
instanceVar是Thread-2 localVar是Thread-2等待...
等待结束 instanceVar是Thread-2 localVar是Thread-2
instanceVar是Thread-3 localVar是Thread-3等待...
等待结束 instanceVar是Thread-3 localVar是Thread-3
instanceVar是Thread-4 localVar是Thread-4等待...
等待结束 instanceVar是Thread-4 localVar是Thread-4
instanceVar是Thread-5 localVar是Thread-5等待...
instanceVar是Thread-6 localVar是Thread-6等待...
.......(省略)
instanceVar是Thread-47 localVar是Thread-47等待...
instanceVar是Thread-48 localVar是Thread-48等待...
等待结束 instanceVar是Thread-48 localVar是Thread-5
等待结束 instanceVar是Thread-48 localVar是Thread-6
等待结束 instanceVar是Thread-48 localVar是Thread-7
 
可以看到一开始比较正常,但是一到后来有的线程执行到一半就没有执行,等到线程48执行到一半,原来没有执行完的线程又开始执行。但是对象变量和局部变量却出错了。
 
这说明
有的线程执行UnSafeObject的process()并没有执行到完毕,时间片就让给了别人,等再次得到时间片的时候,原先的实例变量已经被改变了,所以出现错误。而Thread.sleep 是制造了这个过程。
ps:
   当前测试环境jdk1.5_9 eclipse,同样的代码在jdk1.5 editplus中会有不同,循环次数加大就可以看到该现象。
 

 
写到这里,我突然明白其实这个问题非常简单,就是初学java时介绍同步方法是说的那个问题。但是同步会降低效率。

其实所谓servlet,action的线程安全问题也是这个问题。效率和安全的取舍!

servlet,action如何解决线程安全和效率问题?不采用同步且避免使用类成员

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值