在进行并发编程时,希望通过多线程执行任务让程序运行得更快,会面临很多挑战,比如上下文切换、死锁的问题。
上下文切换
多线程一定快吗?对比并发和串行:
public class ConcurrencyTest{
private static final long count = 100001;
public static void main(String[] args) throws InterruptedException{
concurrency();
serial();
}
private static void serial() {
long start = System.currentTimeMillis();
int a = 0;
for(long i = 0; i < count; i++){
a += 5;
}
int b = 0;
for(long i = 0; i < count; i++){
b--;
}
long time = System.currentTimeMillis() - start;
System.out.println("serial:" + time + "msn b = " + b + " , a = " + a );
}
private static void concurrency() throws InterruptedException {
long start = System.currentTimeMillis();
Thread thread = new Thread(new Runnable(){
@Override
public void run() {
int a = 0;
for(long i = 0; i < count; i++){
a += 5;
}
}
});
thread.start();
int b = 0;
for(long i = 0; i < count; i++){
b--;
}
long time = System.currentTimeMillis() - start;
thread.join();
System.out.println("currency :" + time + "ms, b = " + b);
}
}
经过测试,当并发执行累加操作不超过百万次时,速度会比串行执行累加操作要慢。这是因为线程有创建和上下文切换的开销。
测试上下文切换的次数和时长
使用Lmbench3可以测量上下文切换的时长。
使用 vmstat可以测量上下文切换的次数。
减少上下文切换
减少上下文切换的方法有无锁并发编程、CAS算法、使用最少线程和使用协程。