一、减少线程持有锁的时间
一个方法中,并不是所有的地方都需要同步。所以,只在需要同步的地方,进行加锁操作。
在代码中,可以把同步方法修改为同步代码块,可以减少线程持有锁的时间,从而提高性能。
public synchronized void synMethod() {
methodA();//不需要同步的A方法
methodB();//需要同步的B方法
methodC();//不需要同步的C方法
}
public void synMethod() {
methodA(); //不需要同步的A方法
synchronized (this) {
methodB(); //需要同步的B方法
}
methodC(); //不需要同步的C方法
}
二、减少锁粒度:锁分段技术
将一个对象的数据分割成多个部分,并为每个部分分配一把锁。
我们通常使用HashMap的时候,为了能够保证HashMap的同步性,会使用Collections.synchroinzedMap(map)方法返回一个同步的HashMap。而操作这个HashMap的读线程与写线程会相互阻塞,所以同一时刻只能有一个线程在操作。
在ConcurrentHashMap的源中,我们可以发现,它把整个HashMap拆成了若干个小的segment,每一个segment都是一个小的HashMap。每一个小的HashMap分配一把锁。当一个线程进入了一个小的HashMap,另外的线程可以进入其它的小的HashMap。这样,同一时刻,能让多个线程同时操作。因此,性能得到提高。
三、操作互不影响:锁分离技术
只要操作相不影响,锁就可以分离。比如一个队列,从队列头读取数据,从队列尾写入数据,理论上说他们是不冲突的,也就是说是可以锁分离的。除非队列只有一个数据。锁分离在java中应用延伸的一个例子就是LinkedBlockingQueue。
另外一个锁分离的应用就是 读写锁ReentranceReadWriteLock,读读互不影响,可以同时有多个线程读取数据。
四、其它
还有锁粗化和锁消除。
锁粗化就是把执行时间非常短的方法直接加入到同步方法中,减少重新线程重新因为竞争同步锁带来的资源损耗。
锁消除就是消除掉 JDK 代码中自带的锁,比如消除掉StringBuffer中的同步锁。
.