版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_18505715/article/details/79795728
文章目录
一、join()方法的作用
二、join()和start()调用顺序问题
三、join()方法实现原理
一、join()方法的作用
主要作用是同步,它可以使得线程之间的并行执行变为串行执行。在A线程中调用了B线程的join()方法时,表示只有当B线程执行完毕时,A线程才能继续执行。
看如下代码
class JoinThread implements Runnable
{
//重写run方法
public void run()
{
for(int i = 0; i< 30;i++)
{
System.out.println(Thread.currentThread().getName()+"..."+i);
}
}
}
//main方法如下
public static void main(String[] args) throws InterruptedException
{
JoinThread object = new JoinThread();
Thread t1 = new Thread(object);
Thread t2 = new Thread(object);
t1.start();
t1.join();
t2.start();
/**
* 主线程执行到这里,放弃执行资格,此时活着的线程只有t1和t2,
*
* 那么此时t1和t2交替执行,当t1执行完,主线程才能继续执行,
* 也就是说,主线程重新获取执行资格跟t2是否执行完没有半毛钱关系
*
* */
//t1.join();
for(int j = 0;j < 50;j++)
{
System.out.println(Thread.currentThread().getName()+"..."+j);
}
}
上面程序运行结果 : t1执行完,t2和主线程交替执行。
注意下面细节
join()方法中如果传入参数,则表示这样的意思:如果A线程中掉用B线程的join(10),则表示A线程会等待B线程执行10毫秒,10毫秒过后,A、B线程并行执行。需要注意的是,jdk规定,join(0)的意思不是A线程等待B线程0秒,而是A线程等待B线程无限时间,直到B线程执行完毕,即join(0)等价于join()。
二、join()和start()调用顺序问题
这样讲起来也很简单,我们在线程start()前先把变成join()下就知道结果了。代码就不写了,猜想和实际一致,join()方法必须在线程start()方法调用之后调用才有意义。一个线程都还未开始运行,同步是不具有任何意义的。
.
三、join()方法实现原理
看下源码实现
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
其实,join方法是通过调用线程的wait方法来达到同步的目的的。例如,A线程中调用了B线程的join方法,则相当于A线程调用了B线程的wait方法,在调用了B线程的wait方法后,A线程就会进入阻塞状态。
join方法的原理就是调用相应线程的wait方法进行等待操作的,例如A线程中调用了B线程的join方法,则相当于在A线程中调用了B线程的wait方法,当B线程执行完(或者到达等待时间),B线程会自动调用自身的notifyAll方法唤醒A线程,从而达到同步的目的。