Java多线程编程六 join与线程同步

本文详细介绍了Java中join方法的作用,它用于实现线程同步,确保调用join的线程执行完毕后再执行其他代码。通过示例代码展示了join方法在两个线程间的交互,以及带时限的join方法使用,解释了不同情况下的运行逻辑和耗时。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

join方法的作用是让调用这个方法的线程对象执行完成后才会执行别的线程的代码。
利用join等待线程完成。这里就要引出一个概念:线程同步

/**
 * 利用join等待线程完成后执行
 */
public class JoinDemo1 {
    static int num=0;
    public static void main(String[] args) {
        Thread t1=new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                     num=10;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A");
        t1.start();
        try {
            //t1线程执行玩后,下面的输出语句才会执行,没有这行,输出语句很可能输出0
            t1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(num);
    }
}

例二:两个线程的同步
前面例子只有一个线程,现在变成两个,并且计算总耗时。代码如下。
问题是最后的总耗时是多少?

/**
 * 两个线程join并计算时间
 */
public class JoinDemo2 {
    static int num=0;
    public static void main(String[] args) throws InterruptedException {
        Thread t1=new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                num=10;
            }
        },"A");
        Thread t2=new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                num=10;
            }
        },"B");
        t1.start();
        t2.start();
        long start=System.currentTimeMillis();

        System.out.println("t1 join start");
        t1.join();
        System.out.println("t1 join end");
        System.out.println("t2 join start");
        t2.join();
        System.out.println("t2 join end");

        long end=System.currentTimeMillis();
        System.out.println("cost:"+(end-start));
    }
}

总耗时是5s。
运行逻辑是两个线程差不多同时开始运行,t1调用join后,t2还是会继续运行的,只是main方法后面的代码不运行了。差不多3s后,t1执行完成,调用t2的join方法,main方法后面的代码又卡住,差不多2s后,t2完成,main方法里面的代码继续执行,输出结果。

t1 join start
//停了3s
t1 join end
t2 join start
//停了2s
t2 join end
cast:5001

如果t1和t2 join换个位置会怎么样?
耗费的时间还是5s,t2的join时间几乎为0,因为t2执行完成的时候,t1已经完成了。象征性的join一下。

        System.out.println("t2 join start");
        t2.join();
        System.out.println("t2 join end");
        System.out.println("t1 join start");
        t1.join();
        System.out.println("t1 join end");
t2 join start
//停了5s
t2 join end
t1 join start
t1 join end
cost:5002

有时限的join

join方法还有一个时限参数,可以设置最长等待的时间,如果超过时间就不等待了。

public class JoinDemo3 {
    static int num=0;
    public static void main(String[] args) throws InterruptedException {
        Thread t1=new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                     num=10;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A");
        t1.start();
        long start=System.currentTimeMillis();
        t1.join(2000);
        long end=System.currentTimeMillis();
        System.out.println("cost:"+(end-start));
        System.out.println(num);
    }
}

t1执行完成需要3s但只等待2s,2s后main线程的代码就继续执行了。所以num的值还是0.

cost:2000
0

如果join的时间大于线程实际运行的时间,那么和不加是一样的效果。

public class JoinDemo3 {
    static int num=0;
    public static void main(String[] args) throws InterruptedException {
        Thread t1=new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                     num=10;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A");
        t1.start();
        long start=System.currentTimeMillis();
        t1.join(4000);
        long end=System.currentTimeMillis();
        System.out.println("cost:"+(end-start));
        System.out.println(num);
    }
}
cost:3000
10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值