单例模式加锁,我们加关键字synchronized
分布式锁、redis锁,我们广泛使用lock相关锁
区别
synchronized是Java内置关键字,在JVM层面
Lock是类
synchronized可以给类、方法、代码块加锁
而lock只能给代码块加锁
synchronized不需要手动获取释放锁,使用简单,发生异常自动释放锁,不会造成死锁
而lock需要,而且没有使用unlock()去会造成死锁
@SpringBootTest
@Slf4j
public class TestDo {
@Resource
private RedisUtil redisUtil;
private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
@Test
public void test() {
List idList = new LinkedList<>();
for (int i = 0; i < 10; i++) {
idList.add(Long.valueOf(i));
}
for (Long shopId : idList) {
if (null == shopId) {
continue;
}
String redisLock = "test:demo:" + shopId;
String value = redisUtil.get(redisLock, String.class);
log.info("value:{}", value);
if (Objects.equals(value, shopId.toString())) {
continue;
}
redisUtil.set(redisLock, shopId.toString());
log.info("shopId:{}", shopId);
scheduledExecutorService.execute(() -> {
try {
String threadName = Thread.currentThread().getName();
long threadId = Thread.currentThread().getId();
log.info("线程名称为threadName:{},线程id为threadId:{}",threadName,threadId);
String startDate = formatter.format(new Date());
//模拟业务
try {
//5秒
log.info("start===");
Thread.sleep(5000);
} catch (InterruptedException e) {
log.error("e:{}", e);
}
String endDate = formatter.format(new Date());
} catch (Exception e) {
log.error("threadPool.execute:", e);
} finally {
//释放锁
redisUtil.deleteCache(redisLock);
}
});
}
}
}

循环外边new StringBuilder,循环里边.append(),然后使用,尽量不要打印
看一下一个String类型能吃掉多少内存,这个单位是字节
提个建议,不要在循环圳使用 String拼接,改用StringBuilder的方式
1、栈溢出等情况?
StackOverFlowError:
在main中调用main方法,就会不断压栈执行,知道栈溢出;栈的大小可以是固定大小的,也可以动态变化。
如果动态变化,当栈大小到达整个内存空间不足,就会OutOfMemory异常