1.join的使用
在编程过程中我们经常会在主线程中启动一个子线程处理一个业务,如下所示
public class ChildThread implements Runnable{
private String Tag ="ChildThread : ";
@Override
public void run() {
try {
System.out.println(Tag + Thread.currentThread().getName()+" is start");
Thread.sleep(1000);
System.out.println(Tag + Thread.currentThread().getName()+" is end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
String Tag ="MainThread : ";
System.out.println(Tag +" is start");
Thread thread = new Thread(new ChildThread());
thread.start();
System.out.println(Tag + " deals its own task!");
System.out.println(Tag +" is end");
}
运行结果:
MainThread : is start
MainThread : deals its own task!
MainThread : is end
ChildThread : Thread-0 is start
ChildThread : Thread-0 is end
此时我们发现主线程都已经结束了,子线程还在运行。如果我们需要等待子线程结束再结束主线程该怎么办呢?我们可以使用join()方法,如下修改一下main函数:
public static void main(String[] args) throws InterruptedException {
//...
System.out.println(Tag + " deals its own task!");
thread.join();
System.out.println(Tag +" is end");
}
运行结果:
MainThread : is start
MainThread : deals its own task!
ChildThread : Thread-0 is start
ChildThread : Thread-0 is end
MainThread : is end
此时运行代码,可以看到子线程结束后,主线程才结束了。除了join()方法还有什么方式呢?下面介绍一种更加方便灵活的方法CountDownLatch。
2.CountDownLatch的使用
CountDownLatch类是java并发的辅助类,可以灵活的实现子线程之间的同步,下面看一下代码中的应用:
public static void main(String[] args) throws InterruptedException {
String Tag ="MainThread : ";
CountDownLatch latch = new CountDownLatch(1);
System.out.println(Tag +" is start");
Thread thread = new Thread(new ChildThread(latch));
thread.start();
System.out.println(Tag + " deals its own task!");
latch.await();
System.out.println(Tag +" is end");
}
上面的代码中我们先通过CountDownLatch(int n)的初始化latch,初始化的参数n为需要同步的子线程数,然后在需要等待子线程结束的地方使用await()方法等待。接下来看一下子线程的写法:
public class ChildThread implements Runnable{
private String Tag ="ChildThread : ";
private CountDownLatch latch;
public ChildThread(CountDownLatch latch) {
this.latch = latch;
}
@Override
public void run() {
try {
System.out.println(Tag + Thread.currentThread().getName()+" is start");
Thread.sleep(1000);
System.out.println(Tag + Thread.currentThread().getName()+" is end");
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
首先我们通过构造函数将主线程初始化的CountDownLatch传入子线程,接下来只需要在子线程结束的地方执行countDown()方法就可以了。运行一下主方法,同样可以得到上面的结果。