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

文章通过示例展示了单线程执行20亿次自增操作耗时1063ms,而两个并发线程完成同样操作在加入join方法后耗时617ms,说明了多线程能有效利用CPU多核资源。但要注意线程创建的开销、可能的并发执行以及线程调度的影响。多线程适用于CPU密集型和IO密集型场景,提高系统效率。
摘要由CSDN通过智能技术生成

多线程充分的利用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在摸鱼,就可以给他找点活干,因此可以使用多线程,避免中央处理器过于闲置。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值