start,join,run,countDownLatch区别

1.start:主线程启动时候会执行子线程继承的run方法;

主线程:

public static void main(String[] args) throws Exception{

        Son son=new Son();
        son.start();

}

子线程: 重写Thread方法

public class Son extends Thread{

    @Override
    public void run(){
        System.out.println("子线程执行开始。。。2"+Thread.currentThread().getName());

        try{
            Thread.sleep(3000);
        }catch(Exception e){
            e.printStackTrace();
        }
        System.out.println("子线程执行结束。。。4");

    }


}

运行主方法结果如下:

        子线程执行开始。。。2Thread-0

        子线程执行结束。。。4

主线程启动时候会执行子线程继承的run方法;

2.join:等待上一个线程执行完毕,再去执行下一个线程;

public static void main(String[] args) throws Exception{

        Son son=new Son();
        son.start();
        son.join();
        son.run();

}

运行主方法结果如下:

        子线程执行开始。。。2Thread-0

        子线程执行结束。。。4

        子线程执行开始。。。2main

        子线程执行结束。。。4

1).当join未输入参数时【初始值为0】:先会执行子线程,等子线程执行完毕;主线程再去调son类中的run方法。

start,join,run,countDownLatch区别

 2).当join输入参数,小于子线程整体流程完成时间:会等待子线程启动完毕,等待1000后会启动主线程。

public static void main(String[] args) throws Exception{

        Son son=new Son();
        son.start();
        son.join(1000);
        son.run();

}

运行主方法结果如下:

        子线程执行开始。。。2Thread-0

        子线程执行开始。。。2main

        子线程执行结束。。。4

        子线程执行结束。。。4

join源代码如下:

start,join,run,countDownLatch区别

3.countDownLatch :计算器,类似于栅栏,当计算器为0时,会使主线程运行。

        1)先创建worker类:

public class Worker extends Thread{

    private String name;
    
    private Long time;
    
    private CountDownLatch countDownLatch ;

    public Worker (String name,Long tine,CountDownLatch countDownLatch){
        this.name=name;
        this.time=time;
        this.countDownLatch=countDownLatch;
    }

    @Override
    public void run(){
        try{
            System.out.println(String.format("%s%s",name,"开始工作"));
            Thread.sleep(3000);
            System.out.println(String.format("%s%s%s",name,"工作完成,消耗时间=",time));
            countDownLatch.countDown();
            System.out.println(String.format("%s%s","count",countDownLatch.getCount()));          
        }catch(Exception e){
            e.printStackTrace();
        } 
    }

}

        2)运行main方法:

public static void main(String[] args){

       try{
            CountDownLatch countDownLatch=new CountDownLatch(2);
            Worker worker0=new Worker("worker0",new BigDecimal(Math.random()*2000+3000).setScale(2,BigDecimal.ROUND_HALF_UP).longValue(),countDownLatch);
            Worker worker1=new Worker("worker1",new BigDecimal(Math.random()*2000+3000).setScale(2,BigDecimal.ROUND_HALF_UP).longValue(),countDownLatch);
            Worker worker2=new Worker("worker2",new BigDecimal(Math.random()*2000+3000).setScale(2,BigDecimal.ROUND_HALF_UP).longValue(),countDownLatch);
            worker0.start();
            worker1.start();
            countDownLatch.await();
            System.out.println(String.format("%s%s","工作完成,消耗时间=",Thread.currentThread().getName()));
            worker2.start();
            
        }catch(Exception e){
            e.printStackTrace();
        } 

}

运行主方法结果如下:

       start,join,run,countDownLatch区别 

         3)运行主方法结论:worker2线程会等待worker0,worker1线程执行完毕才会执行;

        4)countDownLatch 与join不同点时,可以灵活的设置countDownLatch.countDown()位置,worker2线程不需要等待worker0,worker1线程执行完毕才会执行,可以设置为worker0,worker1线程工作时就启动worker2线程。

public class Worker extends Thread{

    private String name;
    
    private Long time;
    
    private CountDownLatch countDownLatch ;

    public Worker (String name,Long tine,CountDownLatch countDownLatch){
        this.name=name;
        this.time=time;
        this.countDownLatch=countDownLatch;
    }

    @Override
    public void run(){
        try{
            System.out.println(String.format("%s%s",name,"开始工作"));
            //调整countDownLatch.countDown位置
            countDownLatch.countDown();
            Thread.sleep(3000);
            System.out.println(String.format("%s%s%s",name,"工作完成,消耗时间=",time));
            System.out.println(String.format("%s%s","count",countDownLatch.getCount()));          
        }catch(Exception e){
            e.printStackTrace();
        } 
    }

}

运行主方法结果如下:

start,join,run,countDownLatch区别

 结论:与join最大的区别在于,当countDownLatch计数器为0时,其它线程就会相应执行,而不会等待Thread执行完毕;当join控制线程顺序时,必须等待Thread执行完毕才会继续执行下一个线程。

上一篇:asp.net core middleware


下一篇:SpringApplication.run(xxx.class, args)背后的东东——实现原理