在高并发的环境下,激烈的锁竞争会导致程序性能下降。
1、减小锁持有的时间
在锁的竞争过程中,如果某个线程获得了锁,那其他线程就只有等了,如果该线程持有的时间长,那就会影响系统性能。
public void synchronized function(){
otherCode1();
mutexCode(); //需要同步的代码
otherCode2();
}
//改为
public void function(){
otherCode1();
synchronized {
mutexCode();
}
otherCode2();
}
2、锁粗化
在程序中,应该避免对同一个锁不停地请求,同步和释放。这本身也会消耗系统宝贵的资源,不利于性能优化。
for(int i=0; i<max; i++) {
synchronized(lock) {
}
}
//改成
synchronized(lock) {
for(int i=0; i<max; i++) {
}
}
public void fun() {
synchronized(lock) {
}
//其他不需要同步的工作,但可以很快执行完
synchronized(lock) {
}
}
//改成
public void fun() {
//整合成一个锁
synchronized(lock) {
}
}
3、避免死锁
嵌套使用锁是死锁最主要的原因,类似下面的情况,要么是在一个方法类,要么在多个方法中相互调用。
public void fun1() {
synchronized (obj1) {
synchronized (obj2) {
}
}
}
public void fun2() {
synchronized (obj2) {
synchronized (obj1) {
}
}
}
1. 按顺序加锁
2. 使用定时锁
ReentrantLock. tryLock(long time, TimeUnit unit):在给定时间内尝试获取锁
3. 使用Semaphore
Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。
4. 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源
5. 使用无锁函数