java 多线程中的线程安全问题(Java高手进)

假如我有一个类ClassA这个类是单一实例模式的,系统中只出现它的一个对象而这个类,定义了很多个方法,f1,f2,f3,f4.....这些方法之间并没有公有数据。它们彼此... 假如我有一个类ClassA
这个类是单一实例模式的,系统中只出现它的一个对象

而这个类,定义了很多个方法, f1,f2,f3,f4.....

这些方法之间并没有公有数据。它们彼此是独立的,类似静态方法
(不写设计成静态方法的原因是因为其中有用到泛型)

根据不同的类型参数,将创建不同的ClassA对象,单具体的某个类型参数,它的对象是唯一的。。。

我想问,这样是不是线程安全的。。问题的关键是看 ClassA 的对象的同一方法,被多个线程执行的时候,它们是彼此独立的(也就是占有独立的内存片段,语句存放在独立的堆栈里头)?还是有关系?

望高手指教。。
展开
 我来答
23746021
2010-04-07 · TA获得超过1467个赞
知道小有建树答主
回答量:384
采纳率:0%
帮助的人:396万
展开全部
线程安全跟单例模式没有必然联系。

单例仅保证了一个JVM下仅一个对象,但多个线程有可能同时操作该对象。
线程安全主要体现在,一个线程霸占某资源后,其它线程只有等待而不是抢夺,一旦造成互相抢夺即有可能出现数据读写混乱甚至死锁。
你的f1、f2、f3等没有公共数据,除非这些方法绝对地“自娱自乐”,比如:
public void f1() {
int a, b = 0;
int c = a + b;
}
也就是跟外界一点关系没有,此时不用加synchronized也是安全的。
但一个方法总要跟外界打交道,一旦涉及到外界数据,它就有不安全的隐患,即便是单例模式。

哦,还有,不同的数据是不可能被放在同一“内存片段”中的,都是相互“独立”的。线程体现在CPU时间片段的分配上,线程抢资源抢的也是CPU资源,数据还是那个数据。

methodA(Object o){...}
这个例子是不正确的,Object o仅为形参。虽然一段源代码在加载时要开辟一块内存空间,但运行时并不是在这块空间上。方法每次运行时都会开辟一个新的内存空间,该空间被当前CPU时间片压到栈顶进行读写,在其内创建形参Object o,方法结束后该空间出栈,如未结束即有另一线程运行该方法,则也是在另一个内存空间内重新开始这个过程,被另一个CPU时间片压到栈顶,且Object o始终是形参随方法而消亡,不会与实参混淆。并不是说单例模式就是总在同一内存空间上操作,单例仅保证加载的惟一性,加载是进堆内存的,而运行的先后是依赖栈(谁在栈顶谁进行读写)的。
lydawen
2010-04-07 · TA获得超过3181个赞
知道大有可为答主
回答量:2678
采纳率:50%
帮助的人:1476万
展开全部
无论是类方法或实例方法,当其被调用时,方法中的局部变量才被分配内存空间,方法调用完毕,局部变量即刻释放所占的内存。
根据《java虚拟机规范》里提到的 多个实例在内存中共享一个方法块,方法存放在code segment中的,而且是多个对象共享一个代码空间。
只要你这个方法不持有类变量或实例变量或其它公共资源,是不存在并发同步问题的!
同时在《深入java虚拟机第二版》里有提到,每当线程调用一个java方法时,虚拟机都会在该线程的java 栈中压入一个新帧。而这个新帧自然就成为了当前帧,在执行这个方法时,它使用这个帧来存储参数,局部变量,中间运算结果等数据。 也就是说多个线程调用同一个方法,它们的参数都被压入栈帧,但只有一个栈帧是当前帧,也就不存在你担心的问题
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
wtslh
2010-04-07 · TA获得超过116个赞
知道小有建树答主
回答量:95
采纳率:0%
帮助的人:0
展开全部
既然是单例的,那就是只有一个对象,在内存中只有一份实例。
除非各个方法上有同步锁,否则就不是线程安全的。

特别是涉及到方法的参数,比如有方法
methodA(Object o){...}
那第一个线程传进行一个String,当该方法执行的过程中,另外一个线程又传进来一个Long,那很可能造成methodA产生非预期的结果。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
manyfaces
2010-04-07 · TA获得超过1068个赞
知道小有建树答主
回答量:1808
采纳率:0%
帮助的人:973万
展开全部
是安全的,因为没共享数据,你每次都是创建对象,并不存在对多个线程对同一个对象同时访问的问题,每个方法确实都是一块独立的代码段,只要他们不访问相同的资源就不存在所谓同步问题
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
百度网友845f74e61
2010-04-07 · TA获得超过6929个赞
知道大有可为答主
回答量:4050
采纳率:50%
帮助的人:1591万
展开全部
我觉得不是安全的,一个单例,在有效的生命期内都是独一的,你多线程调用的都是一人上对象的实例,不会因为你不同的时间调用方法而改变方法的引用。

如果一定要按你说的这样用,在你的f1,f2.....方法上加上synchronized,做线程保护吧。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(3)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式