多线程与并发---join方法

多线程与并发—join方法

线程之间并行执行变成串行执行

作用:

  • 调用某个线程的此方法时,这个方法会挂起调用的线程,直到被调用线程结束执行,调用线程才会继续执行
main方法中
Thread t1 = new Thread();
t1.start();
t1.join();
  • 此时main线程(调用线程)被挂起,等待t1线程(被调用线程)调用完成,main线程才会继续执行

源码:

public final void join() throws InterruptedException {
    join(0);
}
//调用线程等待被调用线程执行,但是只等待mills秒,后面变成并行执行
public final synchronized void join(long millis) throws InterruptedException {//同步方法
        long base = System.currentTimeMillis();//获取当前时间毫秒值
        long now = 0;
        if (millis < 0) {//如果等待时间小于0,抛出异常
            throw new IllegalArgumentException("timeout value is negative");
        }
        if (millis == 0) {///如果等待时间等于0,没有设置超时时间,一直要等待该线程执行完(无限等待)
            while (isAlive()) {//需要注意的是,如果当前线程未被启动或者已经终止,则isAlive方法返回false,即意味着join方法不会生效
                wait(0);
            }
        } else { //设置了超时时间
            while (isAlive()) {
                long delay = millis - now;//计算剩余时间
                if (delay <= 0) { //如果剩余等待的时间小于等于0,则终止等待
                    break;
                }
                wait(delay);//等待指定时间
                now = System.currentTimeMillis() - base;//获取此次循环执行的时间
            }
        }
    }
  • isAlive()方法:判断当前线程是否处于活动状态(已经启动,但尚未终止)
  • join方法正常生效,调用join方法的线程对象必须已经调用了start()方法并且未进入终止状态。
  • join方法的本质调用的是Object中的wait方法实现线程的阻塞

案例:

案例01:

/**
 * 加减乘除,顺序执行
 */
public class JoinDemo {
    private static Map<String,Object> resultMap = new HashMap<String,Object>();
    private static int result = 0;
    public static void main(String[] args) throws InterruptedException {

        Thread t1 = new Thread(() -> {
            resultMap.put(Thread.currentThread().getName(),result+1+2);
            System.out.println("t1 is running...");
        });
        Thread t2 = new Thread(() -> {
            resultMap.put(Thread.currentThread().getName(),result+1-2);
            System.out.println("t2 is running...");
        });
        Thread t3 = new Thread(() -> {
            resultMap.put(Thread.currentThread().getName(),result+1*2);
            System.out.println("t3 is running...");
        });
        Thread t4 = new Thread(() -> {
            resultMap.put(Thread.currentThread().getName(), result+(1/2));
            System.out.println("t4 is running...");
        });
        t1.start();
        t1.join();//main线程被挂起,等待t1执行完
        t2.start();
        t2.join();//
        t3.start();
        t3.join();
        t4.start();
        t4.join();
        System.out.println("通过Map.KeySet遍历key和value:");
        Set<String> keySet = resultMap.keySet();
        for (String s : keySet) {
            System.err.println("key:"+s+"   value:"+resultMap.get(s));
        }
        System.err.println(result);
        Thread.sleep(100);
        System.out.println("通过Map.entrySet使用iterator遍历key和value:");
        Iterator<Map.Entry<String, Object>> it = resultMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, Object> entry = it.next();
            System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
        }
        //推荐,尤其是容量大时
        System.out.println("通过Map.entrySet遍历key和value");
        for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
            System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
        }
        Thread.sleep(100);
        System.out.println("通过Map.values()遍历所有的value,但不能遍历key");
        for (Object v : resultMap.values()) {
            System.out.println("value= " + v);
        }
    }

}

案例02:

public class JoinDemo02 {
    public static void main(String[] args) {
        Thread t1=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("t1 is running...");
            }
        });
        //初始化线程二
        Thread t2=new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    t1.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    System.out.println("t2 is running...");
                }
            }
        });
        //初始化线程三
        Thread t3=new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    t2.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    System.out.println("t3 is running...");
                }
            }
        });
        t1.start();
        t2.start();
        t3.start();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值