`

对Java的StringBuffer类线程安全的误解

阅读更多

在Java中,有三个操作字符串的类:

* String: 操作不可修改的字符串

* StringBuffer: 操作可修改的字符串,线程安全

* StringBuilder: 操作可修改的字符串,从Java 1.5开始引入,线程不安全,但操作比StringBuffer快。

 

在开发ugame p7的时候发现我对StringBuffer的线程安全发生误解。

Java的StringBuffer的线程安全并不是说只要操作StringBuffer就是线程安全,

而是说对StringBuffer对象的插入和追加操作对于同一StringBuffer实例而言是原子的,

不允许对同一StringBuffer实例的其它插入和追加操作和这个操作交错执行。

 

也就是说,多个读出写入的原子操作组成的操作并不原子

 

用户界面读取一个StringBuffer静态对象GlobalCall.outputBuffer

然后把它清空:

 

 

	    //用定时器优化日志输出
	    display.timerExec(TIMER_INTERVAL, new Runnable() {
		@Override
    		public void run() {
		    //虽然StringBuffer线程安全,
		    //但在读取toString()和setLength(0)清空之间
		    //存在交错执行的append输入
		    //所以要锁住防止交错
		    synchronized(GlobalCall.outputBuffer) {
			if(GlobalCall.outputBuffer.length() > 0) {
			    logTab.logOutput.append(
				    GlobalCall.outputBuffer.toString()); 
			    GlobalCall.outputBuffer.setLength(0);
			}
		    }
		    display.timerExec(TIMER_INTERVAL, this);
		}
	    });

 

另一方面,在后台线程对这个StringBuffer对象执行追加操作

 

 

	    synchronized(outputBuffer) {
	    	outputBuffer.append(getTimeString() + str + "\n");
	    }

 

如果不加同步锁就会有问题,原因是,在用户界面线程里,append和setLength(0)执行期间,

后台线程可能对这个线程执行append操作。

结果,在此之间执行的append字符串没有来得及显示到界面上,就被setLength(0)删除了。

 

分享到:
评论

相关推荐

    java面试题技术类和人事面试问比较难回答的问题

    13. **HashMap 和 Hashtable 的区别**:HashMap 允许空键值对,是非线程安全的,而Hashtable不允许空键值对,是线程安全的。 14. **final, finally, finalize 的区别**:final 关键字用来声明变量不可改变,方法不...

    Java大数据面试常见问题.pdf

    Java 平台提供了两个类:String 和 StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。String 类提供了数值不可改变字符串,而 StringBuffer 类提供的字符串进行修改。当你知道字符数据要改变的...

    Java大数据面试常见问题.docx

    包括 String 和 StringBuffer 的区别、ArrayList、Vector、LinkedList 的存储性能和特性、HashMap 和 Hashtable 的区别、final、finally、finalize 的区别、switch 语句的使用、多线程的实现方法、Java 中的流类型、...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    1.4.1 类(Class):Java世界中一类物体 14 1.4.2 方法(Method):物体的功能 15 1.4.3 main()方法:所有Java程序执行的起点 15 .1.5 名词解释 16 1.5.1 JDK和Java平台 16 1.5.2 Java编译器(Java Compiler)...

    超级有影响力霸气的Java面试题大全文档

    Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。 13、&和&&的区别。 &是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)。 14、...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    1.4.1 类(Class):Java世界中一类物体 14 1.4.2 方法(Method):物体的功能 15 1.4.3 main()方法:所有Java程序执行的起点 15 .1.5 名词解释 16 1.5.1 JDK和Java平台 16 1.5.2 Java编译器(Java Compiler)...

    Java Bug 模式详解

    这些模式通常源于语言特性、API使用不当或对编程规范的误解。本篇将详细探讨一些常见的Java Bug模式,并提供预防和修复策略。 1. **空指针异常**:在Java中,NullPointerException是开发者最常遇到的错误之一。它...

    Java_EE软件工程师就业求职手册

    - **java.lang包**:Object类的基础方法,Math类的数学运算,String类的字符串操作,StringBuffer类的线程安全字符串构建。 - **java.util包**:集合框架,包括List、Set、Map接口及其实现类,如ArrayList、HashSet...

    23.Java对象作为参数传递是传值还是传引用1

    在Java编程语言中,关于Java对象作为参数传递时的行为,存在一种常见的误解。许多人认为对象是按引用传递,而实际上,Java总是按值传递,包括对象。这里的“值”指的是对象的引用,而不是对象本身。这与C++或C#等...

    Java开发手册(嵩山版)灵魂15问.pdf

    《Java开发手册(嵩山版)灵魂15问》中提到的禁止使用Apache Beanutils进行属性复制的原因主要是性能和安全性的考虑。Apache BeanUtils提供了便捷的属性拷贝功能,但在大规模或高性能应用中,其效率相对较低。相比其他...

    SimpleJava.pdf

    - **类加载机制**:Java虚拟机采用双亲委派模型来加载类,确保了核心类库的稳定性和安全性。 - **类加载时机**:类在首次主动使用时被加载,例如通过反射调用、实例化、静态字段引用等方式触发。 - **初始化过程**:...

    进销存系统文档作业例子

    Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。 10、&和&&的区别。 &是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)。 11、...

Global site tag (gtag.js) - Google Analytics