https://blog.csdn.net/u010365819/article/details/80673964 总结
- 使用join方法
- 使用CountDownLanch
Thread类中的join方法的主要作用就是同步,它可以使得线程之间的并行执行变为串行执行。
join方法必须在线程start方法调用之后调用才有意义。这个也很容易理解:如果一个线程都没有start,那它也就无法同步了。
举一个例子:
程序在main线程中调用t1线程的join方法,则main线程放弃cpu控制权,并返回t1线程继续执行直到线程t1执行完毕 所以结果是t1线程执行完后,才到主线程执行,相当于在main线程中同步t1线程,t1执行完了,main线程才有执行的机会 也就是说:在A线程中调用了B线程的join()方法时,表示只有当B线程执行完毕时,A线程才能继续执行
join方法中如果传入参数,则表示这样的意思:如果A线程中掉用B线程的join(10),则表示A线程会等待B线程执行10毫秒,10毫秒过后,A、B线程并行执行。需要注意的是,jdk规定,join(0)的意思不是A线程等待B线程0秒,而是A线程等待B线程无限时间,直到B线程执行完毕,即join(0)等价于join()。
join方法的原理就是调用相应线程的wait方法进行等待操作的,例如A线程中调用了B线程的join方法,则相当于在A线程中调用了B线程的wait方法,当B线程执行完(或者到达等待时间),B线程会自动调用自身的notifyAll方法唤醒A线程,从而达到同步的目的。可以这样理解:A线程中调用B线程的wait(),那么A一定要持有B线程的锁,此时B对象调用wait(),那么持有该对象锁的对象就要进入阻塞队列,直到调用notify。
那么了解了join方法之后对于主线程要等待子线程结束之后再运行的实现方式就有了,可以在主线程中调用子线程的join方法,这是一种方式。
第二种方式可以使用闭锁:
CountDownLanch 是一个倒数计数器, 给一个初始值(>=0), 然后每一次调用countDown就会减1, 这很符合等待多个子线程结束的场景: 一个线程结束的时候, countDown一次, 直到所有的线程都countDown了 , 那么所有子线程就都结束了.
await: 会阻塞等待计数器减少到0位置. 带参数的await是等待时间,不带参数就是一直等待
countDown: 将当前的计数减1
getCount(): 返回当前的计数
显而易见, 我们只需要在子线程执行之前, 赋予初始化countDownLanch, 并赋予线程数量为初始值.
每个线程执行完毕的时候, 就countDown一下.主线程只需要调用await方法, 可以等待所有子线程执行结束。
关于闭锁,后面再写加一个文章。