java的上下文切换

多线程一定比单线程快吗?

这个答案是否定的,在一定情况下,单线程是比多线程执行效率更高的

影响多线程执行效率有一个关键因素:上下文切换

什么是上下文切换?

cpu通过给每个线程分配时间片来实现多线程,而时间片就是cpu分配给每个线程执行的时间(通常为几十毫秒);而在切换前,会保存程序当前的执行状态,以备cpu再次切换到该线程时候加载当前状态继续往下执行,保存与加载的这个过程被称为是程序的上下文切换。

public class SpeedTest {
    private static final Long count = 10000L;

    public static void main(String[] args) throws InterruptedException {
        concurrency();
        serial();
    }

    private static void concurrency() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread test = new Thread(new Runnable() {
            public void run() {
                int a = 0;
                for (long i = 0; i < count; i++) {
                    a += 5;
                }
            }
        }, "test");
        test.start();
        int b = 0;
        for (long j = 0; j < count; j++) {
            b--;
        }
        long end = System.currentTimeMillis() - start;
        test.join();
        System.out.println("多线程" + end);
    }

    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 j = 0; j < count; j++) {
            b--;
        }
        long end = System.currentTimeMillis() - start;
        System.out.println("单线程" + end);
    }
}

以上代码是java并发编程书籍上的测试案例

循环次数 单线程执行时间/ms 多线程执行时间/ms 并发与单线程速度相比
一亿 111 74 多线程快37ms
一千万 15 11 多线程快34ms
一百万 8 7 多线程快1ms(几乎接近了)
十万 4 4 速度相等
一万 1 2 单线程快1ms
一千 0 2 单线程快2ms

亲测所得:单线程不一定就比多线程快,这是因为多线程有上下文切换的开销

在代码中如何可以减少上下文切换的次数呢?

1、无锁并发编程:多线程竞争锁时会产生上下文切换,所以在使用多线程处理数据时,可以使用一些办法来避免使用锁,例如将数据的ID按照hash算法来取模分段,不同线程处理不同的数据。

2、CAS算法:java的Atomic包使用CAS算法来更新数据,而不使用加锁

3、是用最少线程:避免创建不必要的线程,比如任务很少,但是创建了很多的线程来处理,这样会造成大量线程处于等待状态

4、协程:在单线程里面实现多任务的调度,并在单个线程里维持多个任务间的切换

posted @ 2021-06-20 23:28  七月流星丶  阅读(270)  评论(0编辑  收藏  举报