并发的挑战
几个问题
上下文切换的问题
体现上下文切换影响效率的例子
如何减少上下shang文的切换
- 无锁并发编程
- CAS算法。java的atomic包采用cas算法,不需要加锁
- 使用最少线程
减少上下文切换的实战
使用jstack命令dump信息
/opt/ifeve/java/bin/jstack ${pid} > home/dump
统计dump信息中的线程都处于什么状态
grep java.lang.Thread.State dump | awk '{print $2$3$4$5}' | sort | uniq -c
39 RUNNABLE
21 TIMED_WAITING(onobjectmonitor)
6 TIMED_WAITING(parking)
51 TIMED_WAITING(sleeping)
305 WAITING(onobjectmonitor)
3 WAITING(parking)
打开dump文件查看处于WAITING状态的线程在做什么
死锁的问题
一个死锁例子
private static void deadLock() {
Thread t1 = new Thread(() -> {
synchronized (A) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (B) {
System.out.println("1");
}
}
});
Thread t2 = new Thread(() -> {
synchronized (B) {
synchronized (A) {
System.out.println("2");
}
}
});
t1.start();
t2.start();
}
线程t1和线程t2都在互相等待对方释放锁
避免死锁的方法
- 避免一个线程同时获得多个锁
- 避免一个线程在锁内同时占用多个资源
- 尝试使用定时锁,lock.tryLock(timeout) 来代替内部锁机制
- 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况