A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 迷失的独白 中级黑马   /  2014-9-16 02:49  /  1588 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

刚刚复习到字符串的时候,听毕老师讲到StringBuffer的同步性。
突然就有了疑惑,然后敲代码,验证真实性。
以StringBuffer.appappend()为例
本来先想到的是StringBuffer的实现接口Appendable,
因为StringBuffer, StringBuilder都实现了该接口
所以想从此处证明是否安全,结果,加锁安全,不加乱码
然后直接证实StringBuffer是否安全,结果,加锁安全,不加乱码
这是为什么呢?难道真的不安全吗?
(转载)线程安全 并不是说他的一系列操作是同步的 只是对于他执行某个方法的时候不允许别的线程去改变。针对一个类来说是不是线程安全就要看,多个线程在同时在运行,这些线程可能会同时执行某个方法。但是每次运行结果和单线程执行的结果一样,那么就可以说是线程安全的。
到这里,我才明白,添加代码时的安全不是指顺序添加,而是可不可添加上。

举个例子,地铁排队进站,你力气大你可以先进去,或者去插队(美女和纹身猛男占优)
但是你不能把我打一顿,然后替换我。(某些暴力除外,也许给我钱也可以)


这时,如果加上锁(Lock),那么就是真正的“安全”了,
就像一队特警维护进站秩序,插队,打架,不服从管理的一律拉出去枪毙五分钟(手持核弹的不算)
这样才会按顺序进站,也就是真正的同步安全了。

  1. import java.io.IOException;
  2. import java.util.concurrent.locks.Lock;
  3. import java.util.concurrent.locks.ReentrantLock;
  4.   
  5. public class Test {  
  6.         public static void main(String[] args) throws InterruptedException{

  7.       Test2 t = new Test2();
  8.       Test1 t1 = new Test1(t);
  9.      Thread d1 = new Thread(t1);  Thread d2 = new Thread(t1);
  10.      Thread d3 = new Thread(t1);  Thread d4 = new Thread(t1);
  11.      Thread d5 = new Thread(t1);  Thread d6 = new Thread(t1);      
  12.      d1.start(); d2.start(); d3.start(); d4.start(); d5.start(); d6.start();     
  13.      d1.join(); d2.join(); d3.join(); d4.join(); d5.join(); d6.join();

  14.                 new TPrint().me(t1.str);
  15.                 //new TPrint().me(t.ap);
  16.         }
  17. }

  18. class Test1 implements Runnable {
  19.         StringBuffer str = new StringBuffer();
  20.         private Test2 t;
  21.         private int count = 0;

  22.         public Test1(Test2 t) {
  23.                 this.t = t;
  24.         }

  25.         public void run() {
  26.                 while (count++ < 100000)
  27.                         try {
  28.                                 // t.fun();
  29.                                 // t.fun(str);
  30.                                 //t.fun1(str);
  31.                                 t.fun2(str);
  32.                         } catch (Exception e) {
  33.                                 e.printStackTrace();
  34.                         }
  35.         }
  36. }
  37. class TPrint{
  38.         public void me(StringBuffer str) {
  39.                 String str1 = new String(str);
  40.                 //切割验证是否顺序添加
  41.                 String[] st = str1.split("abcdefghijklmnopqrstuvwxyz");
  42.                 // String[] st = str1.split("0");
  43.                 for (int x = 0; x < st.length; x++)
  44.                         System.out.println(x + "*****\t" + st[x]);
  45.         }
  46. }
  47. class Test2 {
  48.         private Lock lock = new ReentrantLock();
  49.         StringBuffer ap = new StringBuffer();
  50.         char x = 'a';
  51.         int count = 0;

  52.         public void fun(StringBuffer ap) throws Exception {
  53.                 method(ap);
  54.         }

  55.         public void fun1(Appendable ap) throws Exception {
  56.                 method(ap);
  57.         }
  58.        
  59.         public void fun2(Appendable ap) throws Exception {
  60.                 lock.lock();
  61.                 try {
  62.                         method(ap);
  63.                 } finally {
  64.                         lock.unlock();
  65.                 }
  66.         }
  67.         public void fun() throws Exception {
  68.                 lock.lock();
  69.                 try {
  70.                         method(ap);
  71.                 } finally {
  72.                         lock.unlock();
  73.                 }
  74.         }


  75.         private void method(Appendable ap) throws IOException {
  76.                 //添加字符a到z
  77.                 if (x > 'z') {
  78.                         x = 'a';
  79.                         ap.append("0");
  80.                 }
  81.                 ap.append(x++);
  82.                 System.out.println(Thread.currentThread() + "****" + count++ + x);
  83.         }
  84. }
复制代码



9 个回复

倒序浏览
理解的已经很深入了。
回复 使用道具 举报
不明觉厉!                 
回复 使用道具 举报
真心很强大
回复 使用道具 举报
看起来很厉害的样子
回复 使用道具 举报
Seven` 来自手机 中级黑马 2014-9-16 18:53:50
地板
完全不知道怎么证明是不是同步和安全的
回复 使用道具 举报
bj_zlh 中级黑马 2014-9-16 21:18:30
7#
飘过,,,,,
回复 使用道具 举报
{:2_31:}{:2_31:}{:2_31:}{:2_31:}{:2_31:}{:2_31:}
回复 使用道具 举报
chensc 金牌黑马 2014-9-19 19:24:48
9#
学习学习!
回复 使用道具 举报
看起来很厉害的样子,理解的不如你
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马