黑马程序员技术交流社区

标题: 对于StringBuffer和StringBuilder,线程安全的问题。 [打印本页]

作者: 高云飞    时间: 2012-5-10 22:00
标题: 对于StringBuffer和StringBuilder,线程安全的问题。
谁能给我举例说明一下,怎么看出来StringBuffer是安全的,而StringBuilder是不安全的啊。
我是这样实现的:
//final StringBuffer sb = new StringBuffer ();
                final StringBuilder sb = new StringBuilder();
                new Thread (new Runnable () {

                        public void run() {
                                while (true) {
                                        try {
                                                Thread.sleep(2000);
                                        } catch (InterruptedException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                        }
                                        sb.append("====");
                                        //sb.delete(0, 4);
                                        System.out.println(sb);
                                }
                               
                        }
                       
                }).start();
                new Thread (new Runnable () {

                        public void run() {
                                while (true) {
                                        try {
                                                Thread.sleep(2000);
                                        } catch (InterruptedException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                        }
                                        sb.append("AAAA");
                                        //sb.delete(0, 4);
                                        System.out.println(sb);
                                }
                               
                               
                        }
                       
                }).start();
结果是:不管是用StringBuffer还是StringBuilder,都会按照====AAAA的顺序或者AAAA====的顺序老长,没有出现乱序的现象,也就是没有出现过==AA==A===A这样的现象。
我这个方法是否可以体现出来StringBuffer和StringBuilder在线程安全上的差异?只是运行的时间还不够长吗?
有没有更好的办法体现出来??
作者: 黄坚声    时间: 2012-5-10 22:56
StringBuffer   是线程安全的
StringBuilder   不保证线程安全(在1.5中引入的),一般情况下比StringBuffer快。
作者: 黄坚声    时间: 2012-5-10 22:59
另外,
自己编程序想测安全性体现安全性,这个貌似很难,测比较速度快慢比较容易点。
作者: 魏宇    时间: 2012-5-10 23:32
StringBuffer 同步 线程安全 但效率要低一些
StringBuilder 线程不同步 线程不够安全 但要比StringBuffer效率高一些
作者: 高云飞    时间: 2012-5-11 09:23
魏宇 发表于 2012-5-10 23:32
StringBuffer 同步 线程安全 但效率要低一些
StringBuilder 线程不同步 线程不够安全 但要比StringBuffer效 ...

这个我知道,我想的是如何用自己编程,来体现出二者在线程安全性上的不同。你们都没有说到重点。
作者: 随便    时间: 2013-4-2 13:40
我修改了一下你的程序,可以看出线程安全问题了。
  1. public class StringBuilderTest {
  2.         public static void main(String[] args) {
  3.                 final StringBuilder sb = new StringBuilder();
  4.                 //final StringBuffer sb = new StringBuffer ();
  5.                 new Thread(new Runnable() {
  6.                         public void run() {
  7.                                 try {
  8.                                         Thread.sleep(1000);
  9.                                 } catch (InterruptedException e) {
  10.                                         e.printStackTrace();
  11.                                 }
  12.                                 while (true) {
  13.                                         for (int i = 0; i < 20; i++) {
  14.                                                 sb.append("=");
  15.                                         }

  16.                                         System.out.println(sb + " by "
  17.                                                         + Thread.currentThread().getName());
  18.                                 }

  19.                         }

  20.                 }).start();
  21.                 new Thread(new Runnable() {
  22.                         public void run() {
  23.                                 try {
  24.                                         Thread.sleep(1000);
  25.                                 } catch (InterruptedException e) {
  26.                                         e.printStackTrace();
  27.                                 }
  28.                                 while (true) {
  29.                                         for (int i = 0; i < 20; i++) {
  30.                                                 sb.append("A");
  31.                                         }
  32.                                         System.out.println(sb + " by "
  33.                                                         + Thread.currentThread().getName());
  34.                                 }

  35.                         }

  36.                 }).start();
  37.         }

  38. }
复制代码

作者: 随便    时间: 2013-4-2 13:43
StringBuilder的append方法实现代码
  1.     public StringBuilder append(char c) {
  2.         super.append(c);
  3.         return this;
  4.     }
复制代码
StringBuffer的append方法实现代码
  1.     public synchronized StringBuffer append(String str) {
  2.         super.append(str);
  3.         return this;
  4.     }
复制代码
try {
                                                Thread.sleep(2000);//睡眠太长了,另外一个线程肯定已经完成了任务。
                                        } catch (InterruptedException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                        }
                                        sb.append("AAAA");//而且你这样写,没有线程能抢,应该每次加一个A,添加多少次才能看出结果。

作者: 我是王小二    时间: 2021-5-27 13:36
这个代码了厉害了!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2