利用代码证明多线程的优势

多线程充分的利用CPU多核资源

1.单个线程,串行的,完成20亿次自增

public class TestDemo1 {
    //1.单个线程,串行的,完成20亿次自增
    private static final long COUNT = 20_0000_0000;
    private static void serial(){
        //需要把方法执行的时间记录下来
        long beg = System.currentTimeMillis();  //记录当前的毫秒级时间戳
        int a=0;
        for (long i = 0;i<COUNT;i++){
            a++;
        }
        a = 0;
        for (long i = 0;i<COUNT;i++){
            a++;
        }
        long end = System.currentTimeMillis();
        System.out.println("单线程消耗的时间" + (end - beg) +"ms");
    }

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

消耗了1063ms 

  

2.两个线程,并发的,完成20亿次自增 

错误代码: 

public class TestDemo1 {
    //2.两个线程,并发的,完成20亿次自增
    private static final long COUNT = 20_0000_0000;
    private static void concurrency(){
        long beg = System.currentTimeMillis();
        Thread t1 = new Thread(()->{
            int a=0;
            for (long i = 0;i<COUNT;i++){
                a++;
            }
        });
        Thread t2 = new Thread(()->{
            int a=0;
            for (long i = 0;i<COUNT;i++){
                a++;
            }
        });
        t1.start(); //创建线程
        t2.start();
        long end = System.currentTimeMillis();
        System.out.println("多线程消耗的时间" + (end-beg) +"ms");
    }

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

这段代码错误的原因是因为,不仅有t1、t2线程,还有main函数,总共三个线程。不等t1,t2执行完,main线程就往下走了,于是结束计时。正确的做法是等到t1,t2都执行完,才停止计时。

 需要加上join方法:

join是等待线程结束(等待线程把自己的run方法执行完)

在主线程中调用t1.join,就是让main线程等待t1执行完。

public class TestDemo1 {
    //2.两个线程,并发的,完成20亿次自增
    private static final long COUNT = 20_0000_0000;
    private static void concurrency(){
        long beg = System.currentTimeMillis();
        Thread t1 = new Thread(()->{
            int a=0;
            for (long i = 0;i<COUNT;i++){
                a++;
            }
        });
        Thread t2 = new Thread(()->{
            int a=0;
            for (long i = 0;i<COUNT;i++){
                a++;
            }
        });
        t1.start(); //创建线程
        t2.start();
        try {
            t1.join(); //join方法,并引入异常处理
            t2.join();
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("多线程消耗的时间" + (end-beg) +"ms");
    }

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

消耗了617ms 

 3、注意点

两个线程不是单纯的将单线程时间缩短一半,

1、创建线程自身,也是有开销的

2、两个线程在CPU上不一定是纯并行,也可能是并发,一部分时间里是并行的,一部分是并发的

3、线程的调度,也是有开销的。(当前场景中,开销应该是非常小的)

4、 多线程的使用场景

1、在CPU密集型场景

代码中大部分的工作,都是在使用CPU进行运算(如上述案例的++),使用多线程,就可以更好的利用CPU多核计算资源,如人工智能相关的场景,计算量很大。

2、在IO密集型场景

如读写磁盘,读写网卡等。这些场景里,需要花很大的时间进行等待,像这些IO操作,都是几乎不消耗CPU就能完成快速的数据的操作。既然CPU在摸鱼,就可以给他找点活干,因此可以使用多线程,避免中央处理器过于闲置。

猜你喜欢

转载自blog.csdn.net/benxiangsj/article/details/129770094