用于多线程下的StringBuffer和StringBuilder的状态

package org.donkey.app.StringBufferAndStringBuilder;

import java.util.concurrent.CountDownLatch;

/**
 * Created with IntelliJ IDEA.
 * User: Donkey
 * Date: 13-11-24
 * Time: 上午11:28
 * 用于多线程下的StringBuffer和StringBuilder的状态,
 * 其实有人说StringBuffrer是线程安全的而StringBuilder是线程不安全的,这种说法是错误的
 * 这中线程安全是相对的,在StringBuffer中大部分方法都加上了synchronized关键字,使得同一时刻,不会两个线程
 * 同时访问该方法,但在一个线程不安去的环境下用StringBuffer去工作,得到的结果也不一定和预期的一样,就如同本例。
 * 它们的本质的区别在于:StringBuffer的结果与预期不一样是因为逻辑代码的问题,不存在多个线程同时访问而产生未知的
 * 数据问题。而StringBuilder是有可能在同一时刻被多个线程所访问而产生线程同步问题
 */
public class StringBufferAndStringBuilder {
    public static void main(String[] args){
        long startTime = System.currentTimeMillis();
        StringBuffer sb = new StringBuffer();

        StringBuilder sbd = new StringBuilder();
        int threadNum = 1000; //线程数
        //定义正在运行的线程数
        CountDownLatch runningThreadNum = new CountDownLatch(threadNum);
        System.out.println(Thread.currentThread().getName()+"-start");

        //创建多个子线程
        for(int i = 0; i < threadNum; i++){

            new ThreadTest(sb, runningThreadNum).start();
        }

        //等待子线程都执行完了再执行主线程剩下的动作
        try {
            runningThreadNum.await();
            System.out.println(sb.toString());
            System.out.println(Thread.currentThread().getName()+"-end");
            long endTime = System.currentTimeMillis();
            System.out.println("runningTime:"+(endTime-startTime));
        } catch (InterruptedException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

    }
}

class ThreadTest extends Thread{
    private StringBuffer sbd;
    //子线程记数器,记载着运行的线程数
    private CountDownLatch runningThreadNum;
    public  ThreadTest(StringBuffer sbd, CountDownLatch runningThreadNum){
        super();
        this.sbd = sbd;
        this.runningThreadNum = runningThreadNum;
    }
    @Override
    public void run(){
        System.out.println(Thread.currentThread().getName()+"-start");
        for (int i = 0; i < 10; i++){
              if(i == 5){
                  try {
                      Thread.sleep(200);
                  } catch (InterruptedException e) {
                      e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                  }
              }
            sbd.append(i);
        }
        System.out.println(Thread.currentThread().getName()+"-end");


        runningThreadNum.countDown();
    }


}

你可能感兴趣的:(多线程,String,线程安全,StringBuilder,StringBuffer)