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方法。
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源代码如下:
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();
}
}
运行主方法结果如下:
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();
}
}
}
运行主方法结果如下:
结论:与join最大的区别在于,当countDownLatch计数器为0时,其它线程就会相应执行,而不会等待Thread执行完毕;当join控制线程顺序时,必须等待Thread执行完毕才会继续执行下一个线程。