怎么理解Stringbuffer 是线程安全的 stringbuilder是线程不安全的 你看看源码 涉及到 synchronized 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 如果你写了一个全局范围的StringBuffer和StringBuilder...两个线程不能同时修改StringBuffer中的内容,而能同时修改StringBuilder中的东西 如果你只在一个非静态方法中作为局部变量利用一下,完全可以用StringBuilder,它性能好一些 恩 是涉及到synchronized 但是不明白什么情况需要用线程安全的类 什么情况下可以用线程不安全的类 因为线程不安全的类效率高 速度快 java中的全局变量是指类中声明的静态变量 既可以是一个项目里的变量,例如在ServletContext中;又可能是一个类的变量:如果你把你个类的属性,声明为static型的,那就是个全局变量。 而且,如果你的类实例化为单例模式,类本身就是全局的,那里边的变量也就相当于全局的。所有与线程安全相关的知识,都涉及到这个全局问题,如果一点全局性的都不用考虑,每次请求都是new和新创建,基本就不用考虑线程安全问题。 既可以是一个项目里的变量,例如在ServletContext中;又可能是一个类的变量:如果你把你个类的属性,声明为static型的,那就是个全局变量。恩 这个servletcontext里的变量是所有的servlet都可以访问的 每个servlet定义的便利只有那个servlet可以访问 我很疑惑 我以前看JAVA书 只有成员变量和局部变量的概念 今天第一次听说全局变量 加个static不是静态变量了吗 就是所有这个类new出来的对象说公用的 为啥说是全局变量呢 请指点啊 你好 你这句话说反了吧 既然StringBuffer线程是安全的 那么应该两个线程能同时修改StringBuffer的内容啊StringBuilder不安全 所以不能用两个线程同时修改啊 谢谢耐心讲解 有点懂了 对了 StringBuffer是线程安全的 那个StringBuffer应该可以两个线程同时修改StringBuffer的内容吧 当然没说错。a = "bbb";b = a.append("xx");c = a.append("yy");线安 b = bbbxx c=bbbxxyy;线不安 b= bbbxx c=bbbyy; 比如说一个StringBuffer对象,一个线程调用StringBuffer.append("a"),另一个线程调用StringBuffer.append("b"),那它的数据肯定包含"a",和"b"这两个字符。但同样的操作对StringBuilder来说,最终的结果是,数据可能只有"a",也可能只有"b"或同时有"a“也有”b",这是不确定的。 b = a.append("xx");c = a.append("yy");是b:线 a.append("xx");c:线 a.append("yy"); 线程安全,主要是指多线程操作同一个数据时,防止脏数据的产生。主要的应用场景是应用缓存,缓存是整个系统公用的数据,在多线程系统中,线程的异步访问和修改会导致数据产生异常。考虑一个场景,A和B两个线程同时操作缓存中的一条数据,A线程对数据进行自加处理,B线程对数据进行校验,如果校验不过,就清除数据。非线程安全的情况:当A获取到这条数据,准备修改时,B线程进来了,校验完数据,发现数据不正确,就把数据移除了,这时A线程仍旧认为当前持有的数据还是开始获取的数据,这样再做处理就会报空了。线程安全的情况:就是当一个线程需要对这个数据进行改写时,会给这个数据上一个同步锁,比如A线程拿到数据后,给数据加上同步锁,这时候B线程进来了,但是这时候数据已经上锁,B线程则需要等待A线程释放锁之后才能对数据进行操作,这样就防止了脏数据的产生。Java API的Stringbuffer 和 HashTable是在较低版本的JDK中提供的。随着软件项目越来越负责,系统对于性能要求越来越高,然而线程的同步访问对系统性能有很大的影响,所以才会有效率更高的StringBuilder和HashMap的产生。当然在使用这些非线程安全的集合时,线程安全问题就需要开发人员自己控制了。 简单点说就是在多线程环境下,多个线程对同一个StringBuffer类型的对象(不用管这个对象是否是全局变量,只要是同一个对象)做操作时,会是一个同步的操作,StringBuilder就不会是同步操作。 就效率来说 StringBuilder比StringBuffer快 因为后者是线程安全的 每次都要判断锁 看需求用吧 /** * @see java.lang.String#valueOf(java.lang.Object) * @see #append(java.lang.String) */ public synchronized StringBuffer append(Object obj) { super.append(String.valueOf(obj)); return this; }StringBuffer中大部分方法都有synchronized 关键字,保证了在多线程的情况下对统一资源使用的安全性 只要是全局变量,就得考虑同步和并发的问题其实你完全可以自己加锁 把stringbuilder变成(局部)线程安全的 我的理解,线程安全与否就是看线程在运行的过程中,线程里的东西是否有被修改的风险。如果没这个风险就是安全的,有的话就是不安全的。因为多个线程是不可能同时运行的,他具体什么时候运行取决于CPU如何分配时间片。体现到代码里面就是是否用synchronized修饰。假如我定义两个线程,一个是用来做加法的,一个是用来改变值的。同时启动这两个线程,那么,如果线程不安全,启动加法线程的时候应该是3+4的结果,但是万一刚进入线程,还没来得及做加法,这个线程停止了开始改变值的线程,3+4变成了1+4,改变完成后继续加法的线程,你就会看到,你明明是3+4,但是结果却是5。这就是线程不安全。 你分别用两个线程向同一个StringBuffer里面写入字符,最终结果,StringBuffer里的内容总量和两个线程分开写入的总量是一致的,但是前后顺序不能保证,但是,可以保证每一次调用StringBuffer的append方法添加的内容作为一个整体被添加到字符序列里。每次append的内容,作为一个最小的不可分割的单位,被添加到序列中,由于多线程并发,前后顺序不保证。你分别用两个线程向同一个StringBuilder里面写入字符,最终结果,StringBuilder里面的内容总量和两个线程分开写入的总量,会产生不一致的情况(如果楼主测试的情况是一致了,说明并发程度不够高或者添加的字符序列太少,不够线程跑满多个时间片),并且并发填充的字符序列总数,总是小于等于,分开写入的字符序列的字符总量。由于是并发操作,两个线程的append内容前后顺序不能保证,并且,每次调用append方法添加的内容,不一定会作为最小的单位被添加到序列中,有可能会被另一个线程append的内容所覆盖,从而造成上述的不一致状况产生。 在涉及到修改的方法中StringBuffer都使用了synchronized进行同步,而StringBuilder则没有 线程安全即lockfree 也就是说这一个append的调用可以看成原子的虽然你调用他的时候是一个函数 实际上里面的实现很复杂 有很多行代码如果是非线程安全的会如何呢 两个线程调用append的时候 他们会交错执行这一行一行代码一个线程没做完所有修改 这时候状态是不稳定的 另一个线程就开始修改 这样不乱才怪呢非线程安全的共享变量一定要加锁 楼主应该想错了吧?StringBuffer因为线程安全,所以每次只能有一个线程进入,既然只有一个线程进入,那怎么会可能是有两个线程同时能修改StringBuffer中的内容呢? 意思就是比如一个女的是那个stringbuffer对象 两个线程是两个男的 女的在床上躺着 你进去之后就把门锁上 等你俩完事儿了 你出来之后他才能进去 不能3P 请大虾们帮我写出下列的正则表达式 研究反射机制出现的问题 java操作Excel文件,使用jxl.jar包 问下各位大虾,你们学JAVA 有什么心得体会? String s; 和 String s = null; 和String s = "a";有什么区别 文件写操作的问题?为什么不能添加内容进已写入过内容的文件? 有用SWING的吗?交个朋友! JAVA APPLET 出错提示. struts.upload???? ==和equals区别 请教StringBuffer类的两个方法问题 Applet能实现这些吗???
所有与线程安全相关的知识,都涉及到这个全局问题,如果一点全局性的都不用考虑,每次请求都是new和新创建,基本就不用考虑线程安全问题。
StringBuilder不安全 所以不能用两个线程同时修改啊
a = "bbb";b = a.append("xx");
c = a.append("yy");
线安 b = bbbxx c=bbbxxyy;
线不安 b= bbbxx c=bbbyy;
c = a.append("yy");是
b:线 a.append("xx");
c:线 a.append("yy");
考虑一个场景,A和B两个线程同时操作缓存中的一条数据,A线程对数据进行自加处理,B线程对数据进行校验,如果校验不过,就清除数据。
非线程安全的情况:当A获取到这条数据,准备修改时,B线程进来了,校验完数据,发现数据不正确,就把数据移除了,这时A线程仍旧认为当前持有的数据还是开始获取的数据,这样再做处理就会报空了。
线程安全的情况:就是当一个线程需要对这个数据进行改写时,会给这个数据上一个同步锁,比如A线程拿到数据后,给数据加上同步锁,这时候B线程进来了,但是这时候数据已经上锁,B线程则需要等待A线程释放锁之后才能对数据进行操作,这样就防止了脏数据的产生。
Java API的Stringbuffer 和 HashTable是在较低版本的JDK中提供的。随着软件项目越来越负责,系统对于性能要求越来越高,然而线程的同步访问对系统性能有很大的影响,所以才会有效率更高的StringBuilder和HashMap的产生。当然在使用这些非线程安全的集合时,线程安全问题就需要开发人员自己控制了。
/**
* @see java.lang.String#valueOf(java.lang.Object)
* @see #append(java.lang.String)
*/
public synchronized StringBuffer append(Object obj) {
super.append(String.valueOf(obj));
return this;
}StringBuffer中大部分方法都有synchronized 关键字,保证了在多线程的情况下对统一资源使用的安全性
其实你完全可以自己加锁 把stringbuilder变成(局部)线程安全的
体现到代码里面就是是否用synchronized修饰。
假如我定义两个线程,一个是用来做加法的,一个是用来改变值的。同时启动这两个线程,那么,如果线程不安全,启动加法线程的时候应该是3+4的结果,但是万一刚进入线程,还没来得及做加法,这个线程停止了开始改变值的线程,3+4变成了1+4,改变完成后继续加法的线程,你就会看到,你明明是3+4,但是结果却是5。这就是线程不安全。
虽然你调用他的时候是一个函数 实际上里面的实现很复杂 有很多行代码
如果是非线程安全的会如何呢 两个线程调用append的时候 他们会交错执行这一行一行代码
一个线程没做完所有修改 这时候状态是不稳定的 另一个线程就开始修改 这样不乱才怪呢
非线程安全的共享变量一定要加锁