bla*_*ger 1510 java stringbuilder stringbuffer
StringBuffer
和之间的主要区别是StringBuilder
什么?在决定其中任何一个时,是否存在任何性能问题?
sbl*_*ndy 1609
StringBuffer
是同步的,StringBuilder
不是.
pol*_*nts 714
StringBuilder
比不是StringBuffer
因为它更快synchronized
.
这是一个简单的基准测试:
public class Main {
public static void main(String[] args) {
int N = 77777777;
long t;
{
StringBuffer sb = new StringBuffer();
t = System.currentTimeMillis();
for (int i = N; i --> 0 ;) {
sb.append("");
}
System.out.println(System.currentTimeMillis() - t);
}
{
StringBuilder sb = new StringBuilder();
t = System.currentTimeMillis();
for (int i = N; i > 0 ; i--) {
sb.append("");
}
System.out.println(System.currentTimeMillis() - t);
}
}
}
Run Code Online (Sandbox Code Playgroud)
一个试运行给出的数字2241 ms
为StringBuffer
VS 753 ms
的StringBuilder
.
Osc*_*Ryz 240
基本上,StringBuffer
方法是同步的,而StringBuilder
不是.
这些操作"几乎"相同,但在单个线程中使用同步方法是过度的.
这几乎就是它.
此类[StringBuilder]提供与StringBuffer兼容的API,但不保证同步.此类设计用作StringBuffer的替代品,用于单个线程使用字符串缓冲区的位置(通常情况下).在可能的情况下,建议首先使用此类优先于StringBuffer,因为在大多数实现中它会更快.
因此,它取代了它.
同样的事情发生在Vector
和ArrayList
.
Ber*_*t F 165
但是需要在一个例子的帮助下获得明显的差异?
StringBuffer或StringBuilder
StringBuilder
除非你真的试图在线程之间共享缓冲区,否则简单地使用.StringBuilder
是原始同步StringBuffer
类的未同步(开销较小=效率更高)的弟弟.
StringBuffer
先来了.Sun在所有条件下都关注正确性,因此他们将其同步以使其成为线程安全以防万一.
StringBuilder
后来来了.大多数用途StringBuffer
是单线程,并且不必要地支付同步的成本.
由于StringBuilder
是一个简易替换为StringBuffer
不同步时,就不会有任何的例子之间的差异.
如果你正在尝试线程之间共享,你可以使用StringBuffer
,但考虑更高级别的同步是否是必要的,例如,也许不是使用StringBuffer的问题,您应该同步的是使用StringBuilder方法.
use*_*551 76
首先让我们看看相似之处:StringBuilder和StringBuffer都是可变的.这意味着您可以在同一位置更改它们的内容.
差异:StringBuffer也是可变的和同步的.StringBuilder可变,但默认情况下不同步.
synchronized(同步)的含义:当某个东西同步时,多个线程可以访问,并修改它而不会出现任何问题或副作用.StringBuffer是同步的,因此您可以将它与多个线程一起使用而不会出现任何问题.
哪一个使用的时候? StringBuilder:当你需要一个可以修改的字符串时,只有一个线程正在访问和修改它.StringBuffer:当你需要一个可以修改的字符串,并且多个线程正在访问和修改它.
注意:不要不必要地使用StringBuffer,即如果只有一个线程正在修改和访问它,请不要使用它,因为它有很多锁定和解锁代码用于同步,这将不必要地占用CPU时间.除非需要,否则不要使用锁.
Nic*_*zol 51
在单线程中,由于JVM优化,StringBuffer并不比StringBuilder慢得多.在多线程中,您无法安全地使用StringBuilder.
这是我的测试(不是基准,只是测试):
public static void main(String[] args) {
String withString ="";
long t0 = System.currentTimeMillis();
for (int i = 0 ; i < 100000; i++){
withString+="some string";
}
System.out.println("strings:" + (System.currentTimeMillis() - t0));
t0 = System.currentTimeMillis();
StringBuffer buf = new StringBuffer();
for (int i = 0 ; i < 100000; i++){
buf.append("some string");
}
System.out.println("Buffers : "+(System.currentTimeMillis() - t0));
t0 = System.currentTimeMillis();
StringBuilder building = new StringBuilder();
for (int i = 0 ; i < 100000; i++){
building.append("some string");
}
System.out.println("Builder : "+(System.currentTimeMillis() - t0));
}
Run Code Online (Sandbox Code Playgroud)
结果:
字符串:319740
缓冲区:23
构建器:7!
因此,构建器比Buffers更快,并且比字符串连接更快.现在让我们使用Executor进行多线程:
public class StringsPerf {
public static void main(String[] args) {
ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
//With Buffer
StringBuffer buffer = new StringBuffer();
for (int i = 0 ; i < 10; i++){
executorService.execute(new AppendableRunnable(buffer));
}
shutdownAndAwaitTermination(executorService);
System.out.println(" Thread Buffer : "+ AppendableRunnable.time);
//With Builder
AppendableRunnable.time = 0;
executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
StringBuilder builder = new StringBuilder();
for (int i = 0 ; i < 10; i++){
executorService.execute(new AppendableRunnable(builder));
}
shutdownAndAwaitTermination(executorService);
System.out.println(" Thread Builder: "+ AppendableRunnable.time);
}
static void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // code reduced from Official Javadoc for Executors
try {
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow();
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (Exception e) {}
}
}
class AppendableRunnable<T extends Appendable> implements Runnable {
static long time = 0;
T appendable;
public AppendableRunnable(T appendable){
this.appendable = appendable;
}
@Override
public void run(){
long t0 = System.currentTimeMillis();
for (int j = 0 ; j < 10000 ; j++){
try {
appendable.append("some string");
} catch (IOException e) {}
}
time+=(System.currentTimeMillis() - t0);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,StringBuffers需要157毫秒才能获得100000个附加内容.它不是相同的测试,但与之前的37 ms相比,您可以放心地假设使用多线程时StringBuffers追加速度较慢.其原因是,在JIT /热点/编译器/东西使得优化,当它检测到有没有必要检查锁.
但是使用StringBuilder,你有java.lang.ArrayIndexOutOfBoundsException,因为并发线程试图添加它不应该的东西.
结论是您不必追逐StringBuffers.在尝试获得几纳秒之前,在有线程的地方,考虑一下他们在做什么.
Sir*_*dda 35
很好的问题
以下是差异,我注意到:
StringBuffer: -
StringBuffer is synchronized
StringBuffer is thread-safe
StringBuffer is slow (try to write a sample program and execute it, it will take more time than StringBuilder)
Run Code Online (Sandbox Code Playgroud)
StringBuilder的: -
StringBuilder is not synchronized
StringBuilder is not thread-safe
StringBuilder performance is better than StringBuffer.
Run Code Online (Sandbox Code Playgroud)
常见的事情: -
两者都具有相同的签名相同的方法.两者都是可变的.
JRo*_*mio 21
StringBuffer
StringBuilder
StringBuffer
而无需任何其他更改小智 21
StringBuilder
而StringBuffer
几乎是相同的.区别在于StringBuffer
同步而StringBuilder
不是.虽然StringBuilder
比速度快StringBuffer
,但性能差异很小.StringBuilder
是SUN的替代品StringBuffer
.它只是避免了所有公共方法的同步.而不是那样,他们的功能是相同的.
良好用法示例:
如果您的文本将要更改并由多个线程使用,那么最好使用它StringBuffer
.如果您的文本将要更改但由单个线程使用,请使用StringBuilder
.
Vir*_*ual 18
的StringBuffer
StringBuffer是可变的,意味着可以更改对象的值.通过StringBuffer创建的对象存储在堆中.StringBuffer与StringBuilder具有相同的方法,但StringBuffer中的每个方法都是同步的,即StringBuffer是线程安全的.
因此,它不允许两个线程同时访问同一个方法.每个方法一次可以由一个线程访问.
但由于线程安全属性,StringBuffer的性能会受到攻击,因此线程安全也有缺点.因此,当调用每个类的相同方法时,StringBuilder比StringBuffer更快.
StringBuffer值可以更改,这意味着它可以分配给新值.如今它是一个最常见的面试问题,上述课程之间的差异.可以使用toString()方法将String Buffer转换为字符串.
StringBuffer demo1 = new StringBuffer(“Hello”) ;
// The above object stored in heap and its value can be changed .
demo1=new StringBuffer(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuffer
Run Code Online (Sandbox Code Playgroud)
StringBuilder的
StringBuilder与StringBuffer相同,即它将对象存储在堆中,也可以对其进行修改.StringBuffer和StringBuilder之间的主要区别在于StringBuilder也不是线程安全的.StringBuilder很快,因为它不是线程安全的.
StringBuilder demo2= new StringBuilder(“Hello”);
// The above object too is stored in the heap and its value can be modified
demo2=new StringBuilder(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuilder
Run Code Online (Sandbox Code Playgroud)
资源:String Vs StringBuffer与StringBuilder
一个简单的程序,说明了StringBuffer和StringBuilder之间的区别:
/**
* Run this program a couple of times. We see that the StringBuilder does not
* give us reliable results because its methods are not thread-safe as compared
* to StringBuffer.
*
* For example, the single append in StringBuffer is thread-safe, i.e.
* only one thread can call append() at any time and would finish writing
* back to memory one at a time. In contrast, the append() in the StringBuilder
* class can be called concurrently by many threads, so the final size of the
* StringBuilder is sometimes less than expected.
*
*/
public class StringBufferVSStringBuilder {
public static void main(String[] args) throws InterruptedException {
int n = 10;
//*************************String Builder Test*******************************//
StringBuilder sb = new StringBuilder();
StringBuilderTest[] builderThreads = new StringBuilderTest[n];
for (int i = 0; i < n; i++) {
builderThreads[i] = new StringBuilderTest(sb);
}
for (int i = 0; i < n; i++) {
builderThreads[i].start();
}
for (int i = 0; i < n; i++) {
builderThreads[i].join();
}
System.out.println("StringBuilderTest: Expected result is 1000; got " + sb.length());
//*************************String Buffer Test*******************************//
StringBuffer sb2 = new StringBuffer();
StringBufferTest[] bufferThreads = new StringBufferTest[n];
for (int i = 0; i < n; i++) {
bufferThreads[i] = new StringBufferTest(sb2);
}
for (int i = 0; i < n; i++) {
bufferThreads[i].start();
}
for (int i = 0; i < n; i++) {
bufferThreads[i].join();
}
System.out.println("StringBufferTest: Expected result is 1000; got " + sb2.length());
}
}
// Every run would attempt to append 100 "A"s to the StringBuilder.
class StringBuilderTest extends Thread {
StringBuilder sb;
public StringBuilderTest (StringBuilder sb) {
this.sb = sb;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
sb.append("A");
}
}
}
//Every run would attempt to append 100 "A"s to the StringBuffer.
class StringBufferTest extends Thread {
StringBuffer sb2;
public StringBufferTest (StringBuffer sb2) {
this.sb2 = sb2;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
sb2.append("A");
}
}
}
Run Code Online (Sandbox Code Playgroud)
更好地使用StringBuilder
,因为它不同步,因此提供更好的性能。StringBuilder
是旧版本的直接替代品StringBuffer
。
归档时间: |
|
查看次数: |
771775 次 |
最近记录: |