线程的join方法解释

结论:A 线程调用 B 线程对象的 join 方法,则 A 线程会被阻塞,直到 B 线程 挂掉 (Java Doc 原话: Watis for this thread to die)

 

上代码分析

public class Station extends Thread{
    public Station(String name) {
        super(name);
    }
    static int tick = 30;
    int tickets=0;
    // 创建一个静态钥匙
    static Object ob = "aa";
    @Override
    public void run() {
        while (tick > 0) {
            synchronized (ob) {// 锁
                if (tick > 0) {
                    tickets= (int) (Math.random()*10);//随机票数
                    if(tickets>tick)
                        tickets=tick;
                    tick=tick-tickets;
                    System.out.println(getName() + "卖出了" + tickets + "张票");
                    System.out.println("还剩"+tick+"张");
                }
            }
            try {
                sleep(1000);//休息
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(getName()+"卖完啦");
    }
}

 

public class MainC {
    public static void main(String[] args) throws InterruptedException {
        Station station1=new Station("窗口1");
        Station station2=new Station("窗口2");
        Station station3=new Station("窗口3");
        Station station4=new Station("窗口4");
        Station station5=new Station("窗口5");
        station1.start();
        station2.start();
        station3.start();
        station4.start();
        station5.start();
    }
}

不加join方法的运行结果

窗口2卖出了3张票
还剩27张
窗口4卖出了5张票
还剩22张
窗口3卖出了1张票
还剩21张
窗口1卖出了9张票
还剩12张
窗口5卖出了2张票
还剩10张
窗口5卖出了5张票
还剩5张
窗口2卖出了2张票
还剩3张
窗口4卖出了3张票
还剩0张
窗口1卖完啦
窗口2卖完啦
窗口5卖完啦
窗口4卖完啦
窗口3卖完啦

可以看出,不加join方法的时候,5个线程是 并行执行的

 

现在加上join方法

看下结果

 

可以看出当线程运行到

station3.join();的时候,主线程main线程阻塞挂起(即main线程放弃cpu控制权,并返回station3线程继续执行直到线程station3执行完毕),

实际运行的只有前三个线程,所以只有station3执行完成之后才会继续往下执行,然而前三个线程已经把任务执行完了

join()就是join(0)指的是无限等待即join(0)

上源码

/**
 * Waits at most {@code millis} milliseconds for this thread to  //等待设定的时间直到这个线程死亡,join(0)就是一直等待下去
 * die. A timeout of {@code 0} means to wait forever.
 *
 * <p> This implementation uses a loop of {@code this.wait} calls
 * conditioned on {@code this.isAlive}. As a thread terminates the
 * {@code this.notifyAll} method is invoked. It is recommended that
 * applications not use {@code wait}, {@code notify}, or
 * {@code notifyAll} on {@code Thread} instances.
 *
 * @param  millis
 *         the time to wait in milliseconds
 *
 * @throws  IllegalArgumentException
 *          if the value of {@code millis} is negative
 *
 * @throws  InterruptedException
 *          if any thread has interrupted the current thread. The
 *          <i>interrupted status</i> of the current thread is
 *          cleared when this exception is thrown.
 */
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;
        }
    }
}

 

而wait()的意思是让运行这行代码的线程等待(在这里就是main线程等待),

而不是让station3这个线程等待

 

总结:线程A中调用线程B的join方法时,线程A会挂起,直到线程B执行完毕后,才会继续执行线程A。

原理:线程A中调用线程B的join方法时,会使线程A调用自己的wait方法从而进行阻塞线程A,以达到让线程B执行的目的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值