黑马程序员技术交流社区
标题:
StringBuffer同步--真的安全吗?
[打印本页]
作者:
迷失的独白
时间:
2014-9-16 02:49
标题:
StringBuffer同步--真的安全吗?
刚刚复习到字符串的时候,听毕老师讲到StringBuffer的同步性。
突然就有了疑惑,然后敲代码,验证真实性。
以StringBuffer.appappend()为例
本来先想到的是StringBuffer的实现接口Appendable,
因为StringBuffer, StringBuilder都实现了该接口
所以想从此处证明是否安全,结果,加锁安全,不加乱码
然后直接证实StringBuffer是否安全,结果,加锁安全,不加乱码
这是为什么呢?难道真的不安全吗?
(转载)线程安全 并不是说他的一系列操作是同步的 只是对于他执行某个方法的时候不允许别的线程去改变。针对一个类来说是不是线程安全就要看,多个线程在同时在运行,这些线程可能会同时执行某个方法。但是每次运行结果和单线程执行的结果一样,那么就可以说是线程安全的。
到这里,我才明白,添加代码时的安全不是指顺序添加,而是可不可添加上。
举个例子,地铁排队进站,你力气大你可以先进去,或者去插队(美女和纹身猛男占优)
但是你不能把我打一顿,然后替换我。(某些暴力除外,也许给我钱也可以)
这时,如果加上锁(Lock),那么就是真正的“安全”了,
就像一队特警维护进站秩序,插队,打架,不服从管理的一律拉出去枪毙五分钟(手持核弹的不算)
这样才会按顺序进站,也就是真正的同步安全了。
import java.io.IOException;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test {
public static void main(String[] args) throws InterruptedException{
Test2 t = new Test2();
Test1 t1 = new Test1(t);
Thread d1 = new Thread(t1); Thread d2 = new Thread(t1);
Thread d3 = new Thread(t1); Thread d4 = new Thread(t1);
Thread d5 = new Thread(t1); Thread d6 = new Thread(t1);
d1.start(); d2.start(); d3.start(); d4.start(); d5.start(); d6.start();
d1.join(); d2.join(); d3.join(); d4.join(); d5.join(); d6.join();
new TPrint().me(t1.str);
//new TPrint().me(t.ap);
}
}
class Test1 implements Runnable {
StringBuffer str = new StringBuffer();
private Test2 t;
private int count = 0;
public Test1(Test2 t) {
this.t = t;
}
public void run() {
while (count++ < 100000)
try {
// t.fun();
// t.fun(str);
//t.fun1(str);
t.fun2(str);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class TPrint{
public void me(StringBuffer str) {
String str1 = new String(str);
//切割验证是否顺序添加
String[] st = str1.split("abcdefghijklmnopqrstuvwxyz");
// String[] st = str1.split("0");
for (int x = 0; x < st.length; x++)
System.out.println(x + "*****\t" + st[x]);
}
}
class Test2 {
private Lock lock = new ReentrantLock();
StringBuffer ap = new StringBuffer();
char x = 'a';
int count = 0;
public void fun(StringBuffer ap) throws Exception {
method(ap);
}
public void fun1(Appendable ap) throws Exception {
method(ap);
}
public void fun2(Appendable ap) throws Exception {
lock.lock();
try {
method(ap);
} finally {
lock.unlock();
}
}
public void fun() throws Exception {
lock.lock();
try {
method(ap);
} finally {
lock.unlock();
}
}
private void method(Appendable ap) throws IOException {
//添加字符a到z
if (x > 'z') {
x = 'a';
ap.append("0");
}
ap.append(x++);
System.out.println(Thread.currentThread() + "****" + count++ + x);
}
}
复制代码
作者:
小布袋
时间:
2014-9-16 10:38
理解的已经很深入了。
作者:
noiary
时间:
2014-9-16 12:25
不明觉厉!
作者:
马嘉
时间:
2014-9-16 13:20
真心很强大
作者:
lishuliang28
时间:
2014-9-16 17:19
看起来很厉害的样子
作者:
Seven`
时间:
2014-9-16 18:53
完全不知道怎么证明是不是同步和安全的
作者:
bj_zlh
时间:
2014-9-16 21:18
飘过,,,,,
作者:
这个夏天的芬芳
时间:
2014-9-16 22:34
{:2_31:}{:2_31:}{:2_31:}{:2_31:}{:2_31:}{:2_31:}
作者:
chensc
时间:
2014-9-19 19:24
学习学习!
作者:
Apologize丶
时间:
2014-9-20 19:47
看起来很厉害的样子,理解的不如你
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2