java 中为什么说,String是线程安全的

作者&投稿:巴定 (若有异议请与网页底部的电邮联系)
java 中为什么说,String是线程安全的~

String是不可变类,所以是线程安全的
所有不可变类都是线程安全的,线程安全的类不一定是不可变类,如StringBuffer是可变类,靠锁实现线程安全

首先我们谈谈线程安全.
线程安全估计都是老生常谈了.
例子:一个人的账户有银行卡和存折两个终端.共计5000元.当银行卡中取出2000的瞬间,服务器还没更新余额(此时应是3000),存折也向服务器发出取钱3000的请求,服务器查看余额剩余5000给予取款操作.此时存折出钞前,之前银行卡的余额更新到服务器.此时服务器余额为3000元,下个0.05秒存折出钞完毕,将余额更新到服务器,此时余额为2000元.


好了,取了5000元,共5000元最后卡里还剩2000.然后你就进去了.
2.线程安全的解决方案
(1)以上例子,最常用的解决方案就是使用同步语句块 synchronized来保护取款过程.当一个线程在访问该账号正在执行取款操作时,其他线程想要进行取款只能等待.这种方式是以时间换空间.
(2)使用ThreadLocal,ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。这种方式是以空间换时间.
好了,思维拓展结束.现在我们看问题,String为什么是线程安全的呢?
遍寻String的源码,你可能找不到几个synchronized关键字来.是的.我是在引导你走(2).
可是也没有看到ThreadLocal相关的东西啊.这是因为String在设计的时候字符的存储是放在char数组中的,而这个char数组是final的.也就是说,无论你是怎样的多线程环境.你做得修改操作
对原有的对象是没有任何影响的.因为String 在更改的时候是指向了另一个对象(也就是另一个char数组).每个线程修改的时候都是独立的一个char数组,这用的正是(2)方法.所以这个final的char数组才是String 安全的根本.
还有StringBuffer和StringBuilder 两个都是放弃了使用final char数组.所以二者在拼接字符串的时候省内存(不用拼一个字符 new一个char数组了).但是这样就线程不安全了.这就是StringBuilder.而为什么stringBuilder是线程安全的呢.这是因为他的线程安全是用的(1)方法(大量的synchronized).
这里需要解释下,(2)方案为什么能解决线程安全问题.也可以理解为为什么用了final的char数组就可以实现线程安全.原理其实很简单.我们反过来想.线程不安全的情景,无非就是在对同一个对象同时修改的时候,其中一个线程只操作了一半,另一个线程也开始操作.因为线程的执行时间是cpu分配的时间片.并不是谁先执行就是谁先结束.完全有可能a线程先执行修改,在修改没完成的时候b线程也开始操作该对象.结果B线程先修改完毕.想象下.最终的结果可以肯定不是预期的结果.只有这种情况才会出现线程不安全.而当每个线程拥有一个实例的时候.这种情况将不复存在.

线程安全的产生是线程之间同时操作一个变量,比如a线程要把变量x变成1,而b线程要把变量x变成2,当两个线程同时改变这个x的时候,就有了线程安全问题,同时读没关系,写才会有线程安全问题;因为String是不可改变的,所以是线程安全的,改不了。


康马县19719333624: java中为什么说,String是线程安全的? -
乌廖麦特: String是不可变类,所以是线程安全的. 1、所有不可变类都是线程安全的,线程安全的类不一定是不可变类,如StringBuffer是可变类,靠锁实现线程安全.2、StringBuffer方法上都加了synchronized,StringBuilder没有,StringBuilder在多线程...

康马县19719333624: java中的string有什么含义?
乌廖麦特: java中定义了众多的数据类型.其中有八个基本数据类型和各自对应的引用数据类型.但是String类型不在其中,String来自java.lang.String类的,是一个final类型的数据类型,因此不能继承这个类,而且String修饰的字符串不能被修改,这里的...

康马县19719333624: java 中为什么说,String是线程安全的 -
乌廖麦特: 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的. 或者说:一个类或者程序所提供的接口...

康马县19719333624: Java中的到底又没有string,怎么有的说的是无string,而只有String呢? -
乌廖麦特: java肯定有String 问这个问题绝对是初学者 java中对大小写控制的比较严格 说起string 和String这要从C#开始,如果你有接触过C#你会发现java和C#不仅仅是相似,简直就是一样了 这两家公司又经常打架,所以说书写格式以及编码略有不同.而java诞生于C之后,java自主书写限制了大小写的规范,于C#有区别,所以string 不能被定义 String代替string

康马县19719333624: string为什么是引用数据类型 -
乌廖麦特: 简单的说,String是一个类,java里的引用数据类型包括 类,接口,数组 其它区别1. 基本数据类型:变量名指向具体的数值 引用数据类型:变量名指向存数据对象的内存地址,即变量名指向hash值2. 基本数据类型:变量在声明之后java就会立刻分配给他内存空间 引用数据类型:它以特殊的方式(类似C指针)指向对象实体(具体的值),这类变量声明时不会分配内存,只是存储了一个内存地址.3. 基本数据类型:使用时需要赋具体值,判断时使用“==”号 引用数据类型:使用时可以赋null,判断时使用equals方法

康马县19719333624: java中,string是什么意思 -
乌廖麦特: 1、String是字符串 申明字符串类的变量都用这个类型2、可以查看java api 看String类有哪些方法 随便说几个吧 split(),substring()...一些对字符传的操作 tob1112014-10-08

康马县19719333624: 在java中“String”这个关键字是什么意思? 通常在哪些情况下会用到它? -
乌廖麦特: 字符串啊,定义一个字符串的时候用呗,你想打印一句话,就可以String a=“hello”; System.out.println(a);

康马县19719333624: Java中的字符串不是一个零结尾的数组,而是一个真正的对象,这里的零结尾的数组是指什么? -
乌廖麦特: C里面的字符串是通过数组来实现的,也就是说字符串就是字符数组.它有一个结束标记,就是所谓的\0.而java中的String不是拿数组来实现的,而是通过对象的方式实现的,所以String不是基本的数据类型,而是一个对象

康马县19719333624: 为什么说Java的String对象是不可变的 -
乌廖麦特: 今天晚上部门领导开会的时候,又突然想起来这个问题,这里记录下来自己的理解,期待以后会有更深刻的收获. 根据JDK中java.lang.String的源码进行分析,从中可以得出String类型的对象不可变的原因,大致上有如下两个: 1、java.lang....

康马县19719333624: java中String是做什么的?
乌廖麦特: String 是用来申明字符串的啊 比如string dd="abcdefg";就是表示对abcdefg字符串的申明

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网