1.1上下文切换
单核处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给各个线程的时间,因为时间片非常短,所以CPU通过不停的切换线程执行。
CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是在切换之前会保存上一个任务的状态,以便下一次切换回下一个任务时,可以再加载这个任务的状态,所以任务从保存到在加载的过程就是一次上下午切换。
这就像我们同时读两本书,当我们再度一本英文的技术书时,发现某个单词不认识,于是打开英文词典,但是在放下技术书之前我们需要记下这本书读到了多少页的多少行,等查完单词之后,在能够继续读这本书。这样切换会影响读书的效率,同样上下文切换也会影响多线程的执行速度。
1.1.1多线程一定快吗
public class ConcurrencyTest { private static final long count = 100001; public static void main(String[] args) throws InterruptedException { concurrency(); serial(); } private static void concurrency() throws InterruptedException { long startTime = System.currentTimeMillis(); Thread thread = new Thread(() -> { 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--; } thread.join(); long endTime = System.currentTimeMillis(); System.out.println(endTime - startTime+"ms,b = "+b); } private static void serial(){ long startTime = 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 endTime = System.currentTimeMillis(); System.out.println(endTime - startTime+"ms,b = "+b+"---a="+a); } }
从表中发现,当并发执行累加操作不超过百万次时,速度会比串行执行累加操作要慢,为什么并发执行的速度会比串行慢呢?这是因为线程的创建和上下文切换的开销。
1.1.2 测试上下文的切换次数和时长