JAVA并发编程主要面临的几个问题:安全性,活跃性,性能

概述

java并发编程的问题主要集中在安全性、活跃性、性能3个问题

安全性

主要防止竞态问题(race condition),如下代码,add10k中的set(get()+1) 是不安全的,因为他要依赖get方法的结果在set。虽然set和get加了锁但是+1这步操作不是原子性的操作。(有可能get俩个一样的值+1,在set回去,影响了预期结果),这种后面的操作依赖前面操作的结果的操作被称为竞态操作。

解决方法

  1. 加锁synchronized(lock){}解决
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Test {
private long count = 0;
synchronized long get(){
return count;
}
synchronized void set(long v){
count = v;
}
void add10K() {
int idx = 0;
while(idx++ < 10000) {
set(get()+1)
}
}
}

活跃性

要注意活锁和饿死的关系。

  • 饿死只一个线程被阻塞住或者锁住,但是一直没有得到资源,导致程序一直无法执行下去
  • 活锁:活锁是指线程一直尝试获取资源但是因为条件没法满足所以一直没法获取资源。和死锁相比,死锁是线程阻塞程序无法运行,活锁的线程的状态一直没有被锁住,一直在尝试获取资源,很快会耗光cpu的资源。

解决方法:

  • 饿死可以采用公平锁,用fifo队列来解决锁争抢
  • 活锁:可以采用不同线程阻塞一个随机时间。减少竞争。

性能问题

因为并发变成要对数据加锁,可能会影响系统的并发度,某些操作会变为串行,可以考虑用jdk里的并发包里提供的工具类解决,里面有许多无锁的工具。