java中StringBuffer和StringBuilder的区别
StringBuffer:jdk1.0就有,线程安全,但是速度慢,效率低.
StringBuilder:jdk1.5出来的,线程不安全,但是速度快,效率高.
----------------------------------------------------------------------------------------------------
1.针对线程安全与否进行代码比较
StringBuilder:
package com.zr.concurrency.test.notsafe.common;
import com.zr.concurrency.annotation.ThreadNotSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
/**
* @description: StringBuilder用在多线程
* @author: liangrui
* @create: 2020-01-02 10:26
**/
@Slf4j
@ThreadNotSafe
public class StringExample1 {
//请求总数
private static int clientTotal=5000;
//同时并发执行的线程数
private static int threadTotal=200;
//创建StringBuilder类
private static StringBuilder stringBuilder=new StringBuilder();
/**
* 每个线程执行的方法
*/
private static void update(){
stringBuilder.append("1");
}
public static void main(String[] args) throws InterruptedException {
//创建线程池
ExecutorService executorService= Executors.newCachedThreadPool();
//创建Semaphore类控制并发线程数
Semaphore semaphore=new Semaphore(threadTotal);
//创建CountDownLatch类计数线程执行次数,执行clientTotal.countDown()方法,从clientTotal开始计数每次-1,当执行到0,调用clientTotal.await()方法放行
CountDownLatch countDownLatch=new CountDownLatch(clientTotal);
for (int i = 0; i < clientTotal; i++) {
executorService.execute(
() -> {
try {
//200个并发线程许可1个线程执行
semaphore.acquire();
//执行任务
update();
//线程释放
semaphore.release();
}catch (Exception e){
log.error("exception",e);
}
//线程计数-1
countDownLatch.countDown();
}
);
}
//当线程计数到0,此方法才执行,线程不再封闭
countDownLatch.await();
//释放线程池资源
executorService.shutdown();
//输出字符串长度
log.info("size:{}",stringBuilder.length());
}
}
运行结果:4975不是5000,线程不安全
11:31:00.605 [main] INFO com.zr.concurrency.test.notsafe.common.StringExample1 - size:4975
StringBuffer:
package com.zr.concurrency.test.safe.common;
import com.zr.concurrency.annotation.ThreadNotSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
/**
* @description: StringBuffer用在多线程
* @author: liangrui
* @create: 2020-01-02 10:26
**/
@Slf4j
@ThreadNotSafe
public class StringExample2 {
//请求总数
private static int clientTotal=5000;
//同时并发执行的线程数
private static int threadTotal=200;
//创建StringBuffer类
private static StringBuffer stringBuffer=new StringBuffer();
/**
* 每个线程执行的方法
*/
private static void update(){
stringBuffer.append("1");
}
public static void main(String[] args) throws InterruptedException {
//创建线程池
ExecutorService executorService= Executors.newCachedThreadPool();
//创建Semaphore类控制并发线程数
Semaphore semaphore=new Semaphore(threadTotal);
//创建CountDownLatch类计数线程执行次数,执行clientTotal.countDown()方法,从clientTotal开始计数每次-1,当执行到0,调用clientTotal.await()方法放行
CountDownLatch countDownLatch=new CountDownLatch(clientTotal);
for (int i = 0; i < clientTotal; i++) {
executorService.execute(
() -> {
try {
//200个并发线程许可1个线程执行
semaphore.acquire();
//执行任务
update();
//线程释放
semaphore.release();
}catch (Exception e){
log.error("exception",e);
}
//线程计数-1
countDownLatch.countDown();
}
);
}
//当线程计数到0,此方法才执行,线程不再封闭
countDownLatch.await();
//释放线程池资源
executorService.shutdown();
//输出字符串长度
log.info("size:{}",stringBuffer.length());
}
}
运行结果:5000表示线程安全
11:39:42.051 [main] INFO com.zr.concurrency.test.safe.common.StringExample2 - size:5000