最直白的方式直面Java多线程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sureSand/article/details/82227381

毫无疑问,网上关于多线程的讲解很多,各种概念也很复杂,我们该怎么去理解多线程?该如何最直观的面对它,先看一段简单的代码:

package cn.com;

public class TestMainNoRunnable {
  public static void main(String[] args) {
        long startTime=System.currentTimeMillis();   //获取开始时间
        double sum = 0;
        for(int i=0;i<2000000000;i++){
            sum += i;
        }
        System.out.println(sum);
        long endTime=System.currentTimeMillis(); //获取结束时间
        System.out.println("程序运行时间: "+(endTime-startTime)+"ms");
    }
}

这段代码做的事情是从1到2000000000的累加,最终输出:

1.99999999806711398E18
程序运行时间: 2761ms

好,那么我们当然可以将这段累加拆分到两个线程去执行,然后将两个线程的结果合并。

线程1:从0累加到800000000

package cn.com;

import java.util.concurrent.CountDownLatch;

public class TestRunnable1 implements Runnable{

      double sum1 = 0;

       @Override 
       public void run(){
            for(int i =0;i<800000000;i++){
                sum1 += i ;
            }
        }
}

线程2:从800000000累加到2000000000:

package cn.com;

import java.util.concurrent.CountDownLatch;

public class TestRunnable2 implements Runnable{

       double sum2 = 0;
       @Override 
       public void run(){
            for(int i =800000000;i<2000000000;i++){
                sum2 += i ;
            }
        }
}

主线程合并线程一和线程二的结果:

package testWSO2;

import java.util.concurrent.CountDownLatch;

public class TestRunnaleMain {

    public static void main(String[] args) throws InterruptedException {
        long startTime = System.currentTimeMillis(); // 获取开始时间
        TestRunnable1 t1 = new TestRunnable1();
        TestRunnable2 t2 = new TestRunnable2();

        Thread t1s = new Thread(t1);
        t1s.start();

        Thread t2s = new Thread(t2);
        t2s.start();
        t2s.join();//待需要执行时间较长的t2线程结束再继续执行主线程,否则主线程结束了,t1和t2还没计算完
        System.out.println("sum1= " + t1.sum1);
        System.out.println("sum2= " + t2.sum2);
        double sum =t1.sum1+t2.sum2;
        System.out.println("sum3= " + sum);
        long endTime = System.currentTimeMillis(); // 获取结束时间        
        System.out.println("程序运行时间: " + (endTime - startTime) + "ms");
    }
}

最终输出:

sum1= 3.1999999926710899E17
sum2= 1.67999999880559053E18
sum3= 1.99999999807269939E18
程序运行时间: 1753ms

可以发现比直接累加1到2000000000节省了近一秒时间,大家这么一看是不是很直观的感受到两个多线程的好处了。

大家可以改成1到200的累加,会发现单线程会比两个线程还快,而且线程越多这里越慢,这里就可以理解了多线程上下文的切换也需要时间,所以一个cpu能执行的搓搓有余何必去切换多线程呢?就是说有时候并不是多线程就好,要合理根据自己的业务来设计多线程。

其中 t2s.join()是为了让执行时间较长的t2线程结束再继续执行主线程,否则主线程结束了,t1和t2还没计算完,这里并不是最好的办法,推荐使用Java自带的CountDownLatch计数器来解决这个问题。

猜你喜欢

转载自blog.csdn.net/sureSand/article/details/82227381
今日推荐