StringBuilderはStringBufferに比べてなぜスレッドが安全ではないのか

2122 ワード

StringBuilderスレッドが安全でない例
package com.xiva.demo;
public class StringBuilderDemo extends Thread { 
	private StringBuilder sb; 
	public StringBuilderDemo(String name,StringBuilder sb) { 
		super(name); 
		this.sb = sb; 
	} 
	
	@Override 
	public void run() { 
		for (int i = 0; i < 10000; i++) { 
			sb.append("abc");
//			System.out.println(Thread.currentThread().getName()+sb.toString());
		} 
	} 
 

	public static void main(String[] args) { 
		StringBuilder sBuilder = new StringBuilder(); 
		StringBuilderDemo mt = new StringBuilderDemo("sBuilder ",sBuilder); 
//		new Thread(mt).start();
		mt.start();
		for (int i = 0; i < 10000; i++) { 
			sBuilder.append("abcd"); 
		}
		System.out.println("main"+sBuilder.length());
//		System.out.println("main"+sBuilder.toString()); 
	}
} 

mainが印刷したsBuilderの長さが定まらない、すなわちmtスレッドが実行されている場合、main関数はsBuilderに影響を及ぼしているが、以下の例では、印刷した(スレッドは安全)長さは一定である!
 
 
 
package com.xiva.demo;

public class StringBufferDemo extends Thread { 
	private StringBuffer sBuffer; 
	public StringBufferDemo(String name,StringBuffer sb) { 
		super(name); 
		this.sBuffer = sb; 
	} 
	
	@Override 
	public void run() { 
		for (int i = 0; i < 10000; i++) { 
			sBuffer.append("abc");
//			System.out.println(Thread.currentThread().getName()+sb.toString());
		}
		
	} 
 

	public static void main(String[] args) { 
		StringBuffer sBuffer = new StringBuffer(); 
		StringBufferDemo mt = new StringBufferDemo("sBuffer ",sBuffer);
		mt.start();
//		new Thread(mt).start();
//		new Thread(mt).start();
		for (int i = 0; i < 10000; i++) { 
			sBuffer.append("abcd"); 
		}
		while(mt.isAlive()){ 
		}
		System.out.println(sBuffer.length()); 
	}
}