1.并发编程挑战-上下文切换

返回主目录

并行和串行执行

package com.qdb.thinkv.thread.base;

/** 
 * 问题:多线程一定快吗?不一定,通过调整 count分别设置 比如1w 和 1亿 进行比较
 * 思考:如何减少上下文切换?
 */
public class ConcurrencyTest {
    public static final long count=1000000000L;
    public static void main(String[] args) throws InterruptedException {
        concurrency();
        seriai();
    }
    
    public static void concurrency() throws InterruptedException{
        long start=System.currentTimeMillis();
        Thread thread=new Thread(new Runnable(){
            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--;
        }
        thread.join();
        long time=System.currentTimeMillis()-start;
        System.out.println("concurrency"+time+"ms,b="+b);
    }
    
    public static void seriai(){
        long start=System.currentTimeMillis();
        int a=0;
        for (long i = 0; i < count; i++) {
            a+=5;
        }
        long time=System.currentTimeMillis()-start;
        System.out.println("seriai"+time+"ms,a="+a);
        start=System.currentTimeMillis();
        int b=0;
        for (long i = 0; i < count; i++) {
            b--;
        }
        time=System.currentTimeMillis()-start;
        System.out.println("seriai"+time+"ms,b="+b+",a="+a);
    }
}

 总结:线程有创建和上下文切换的开销。

减少上下文切换的方法有无锁并发编程、CAS算法、使用最少线程和使用协程。

1.无锁并发编程。

多线程竞争锁时,会引起上下文切换,多线程处理数据时,可以用一些办法来避免使用锁。如数据的ID按照Hash算法取模分段,不同的线程处理不同段的数据。

2.cas算法。

java 的atomic包使用cas算法来更新数据,不需要加锁。

3.使用最少的线程。

避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这样会造成大量线程都处于等待状态。

4.协程

在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换。

原文地址:https://www.cnblogs.com/tianzhiyun/p/9128608.html