学习总结
- 《Linux Shell 脚本攻略》这本书学习到了第三章(83/268)
- 开始学习《JAVA并发编程的艺术》这本书
- 用
jstack
查看死锁的情况 - 大概了解了
volatile
在CPU指令集的处理逻辑
明日安排
- 继续阅读《JAVA并发编程的艺术》这本书
笔记内容
《JAVA并发编程的艺术》
- 如何减少上下文切换?
- 无锁并发编程。多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以用一些办法来避免使用锁,如将数据的ID按照Hash算法取模分段,不同的线程处理不同段的数据。
- CAS算法。Java的Atomic包使用CAS算法来更新数据,而不需要加锁。
- 使用最少线程。避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这样会造成大量县城都处于等待状态。
实战
用jstack
命令查看进程中是否存在大量WAITING
状态的进程,
由此判断线程池大小是否合适。通过减少空闲线程数量减少上下文切换次数
模拟死锁
模拟代码如下
public class 模拟死锁 {
private final static String A = "A";
private final static String B = "B";
@Test
public void test() throws InterruptedException {
Thread threadA = new Thread(()->{
synchronized(A){
try {
Thread.sleep(100);
synchronized (B){
System.out.println("Get");
}
} catch (InterruptedException e) {
}
}
});
Thread threadB = new Thread(()->{
synchronized(B){
try {
Thread.sleep(100);
synchronized (A){
System.out.println("Get");
}
} catch (InterruptedException e) {
}
}
});
threadA.start();
threadB.start();
threadA.join();
System.out.println("END");
}
}
使用jstack
,输出的结果里已经有了关于死锁的提示信息
virde@virde:~$ jps -l 76342 org.jetbrains.jps.cmdline.Launcher 76424 jdk.jcmd/sun.tools.jps.Jps 67466 com.intellij.idea.Main 76364 com.intellij.rt.junit.JUnitStarter 76126 org.jetbrains.idea.maven.server.RemoteMavenServer36 67934 org.jetbrains.idea.maven.server.RemoteMavenServer36 virde@virde:~$ jstack 76364 2021-04-26 15:43:08 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.181-b13 mixed mode): Java stack information for the threads listed above: …… …… =================================================== "Thread-1": at 多线程.模拟死锁.lambda$test$1(模拟死锁.java:26) - waiting to lock <0x000000076d73f678> (a java.lang.String) - locked <0x000000076d73f6a8> (a java.lang.String) at 多线程.模拟死锁$$Lambda$2/380894366.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) "Thread-0": at 多线程.模拟死锁.lambda$test$0(模拟死锁.java:16) - waiting to lock <0x000000076d73f6a8> (a java.lang.String) - locked <0x000000076d73f678> (a java.lang.String) at 多线程.模拟死锁$$Lambda$1/1068824137.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) Found 1 deadlock. virde@virde:~$
避免死锁的几个常见方法
- 避免一个线程同时获取多个锁
- 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。
- 尝试使用定时锁,使用
lock.tryLock(timeout)
来替代使用内部锁机制 - 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况
IDEA lombok
报错解决记录
项目中使用了lombok
,mvn构建的时候没报错,但是运行时报错。
get,set方法找不到。
百度了解到,maven版本与idea lombok 版本不一致可能会报错。
在根目录的pom.xml
中将lombok
更新至最新版本。还是报错。
查看项目中External Libraries
目录中的文件发现,
存在两个版本的lombok
Maven:org.projectlombok:lombok:1.18.10
Maven:org.projectlombok:lombok:1.18.20
我明明引入了最新版本1.18.20
,那么1.18.10
版本哪来的?
再次排查pom.xml
文件,原来是子项目的pom.xml
引入了低版本。
子项目去掉引用,问题解决