您的位置:首页 > Web前端

线程不安全类 示例(一)StringBuilder VS StringBuffer

2019-03-28 17:14 393 查看

线程不安全类

  • 如果一个类的对象同时可以被多个线程访问,如果不做特殊的同步和并发处理,那么这个类就很容易表现出线程不安全的现象,比如抛出异常,逻辑处理错误;

StringBuilder示例

  • StringBuilder是线程不安全的;
  • StringBuilder虽然线程不安全,但是性能更高,在方法中以局部变量的方式使用,可以做到线程封闭,从而避免了线程不
import com.example.concurrency.annotations.NotThreadSafe;
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;

@Slf4j
@NotThreadSafe
public class StringExample1 {

// 请求总数
public static int clientTotal = 5000;

// 同时并发执行的线程数
public static int threadTotal = 200;

public static StringBuilder stringBuilder = new StringBuilder();

public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
final Semaphore semaphore = new Semaphore(threadTotal);
final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
for (int i = 0; i < clientTotal ; i++) {
executorService.execute(() -> {
try {
semaphore.acquire();
update();
semaphore.release();
} catch (Exception e) {
log.error("exception", e);
}
countDownLatch.countDown();
});
}
countDownLatch.await();
executorService.shutdown();
log.info("size:{}", stringBuilder.length());
}

private static void update() {
stringBuilder.append("1");
}

}

输出:

  • 不等于5000,线程不安全;

17:10:24.767 [main] INFO com.example.concurrency.example.commonunsafe.StringExample1 - size:4945

StringBuffer示例

  • StringBuffer是线程安全的;
import com.example.concurrency.annotations.ThreadSafe;
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;

@Slf4j
@ThreadSafe
public class StringExample2 {

// 请求总数
public static int clientTotal = 5000;

// 同时并发执行的线程数
public static int threadTotal = 200;

public static StringBuffer stringBuffer = new StringBuffer();

public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
final Semaphore semaphore = new Semaphore(threadTotal);
final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
for (int i = 0; i < clientTotal ; i++) {
executorService.execute(() -> {
try {
semaphore.acquire();
update();
semaphore.release();
} catch (Exception e) {
log.error("exception", e);
}
countDownLatch.countDown();
});
}
countDownLatch.await();
executorService.shutdown();
log.info("size:{}", stringBuffer.length());
}

private static void update() {
stringBuffer.append("1");
}

}

输出:

  • 等于5000,线程安全;

17:11:48.784 [main] INFO com.example.concurrency.example.commonunsafe.StringExample2 - size:5000

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: