zoukankan      html  css  js  c++  java
  • join方法的深入探究

    join的探究

    首先明确join的作用:t.join()方法只会使主线程(或者说是t.join()的线程)进入等待池并等待t线程执行完毕后才被唤醒。但是并不会影响同一时刻其他处在运行状态的线程。

    下面来分析一下有无join()的差别:

    无join时:

    // 资源类
    package com.join;
    
    public class ThreadTest extends Thread{
        private String name;
    
        public ThreadTest(String name) {
            this.name = name;
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.println(name+"--->"+i);
            }
        }
    }
    
    
    // 测试方法
    package com.join;
    
    public class Demo {
        public static void main(String[] args) throws InterruptedException {
            ThreadTest t1 = new ThreadTest("A");
            ThreadTest t2 = new ThreadTest("B");
    
            t1.start();
            System.out.println("t1111111111111111111111111111111");
            t2.start();
            System.out.println("t2222222222222222222222222222222");
    
        }
    }
    
    
    
    运行结果
    t1111111111111111111111111111111
    A--->0
    A--->1
    A--->2
    A--->3
    A--->4
    t2222222222222222222222222222222
    B--->0
    B--->1
    B--->2
    B--->3
    B--->4
    
    

    可以看出:t1,t2线程以及main执行时随机无序的。

    但是加入join()时候:

    package com.join;
    
    public class Demo {
        public static void main(String[] args) throws InterruptedException {
            ThreadTest t1 = new ThreadTest("A");
            ThreadTest t2 = new ThreadTest("B");
    
            t1.start();
            t1.join();
            System.out.println("t1111111111111111111111111111111");
            t2.start();
    
            System.out.println("t2222222222222222222222222222222");
    
        }
    }
    
    

    可以看出t2线程在线程t1之后执行:

    package com.join;
    
    public class Demo {
        public static void main(String[] args) throws InterruptedException {
            ThreadTest t1 = new ThreadTest("A");
            ThreadTest t2 = new ThreadTest("B");
    
            t1.start();
            
            System.out.println("t1111111111111111111111111111111");
            t2.start();
            t1.join();
            System.out.println("t2222222222222222222222222222222");
    
        }
    }
    
    
    t1111111111111111111111111111111
    A--->0
    A--->1
    A--->2
    A--->3
    B--->0
    B--->1
    B--->2
    B--->3
    B--->4
    A--->4
    t2222222222222222222222222222222
    
    

    这种情况可以看出来:t1与t2仍然交替打印,随机无序的。

    为了深入理解,我们看一下join()的源码:

    public final void join() throws InterruptedException {
            join(0);            //join()等同于join(0)
        }
    
    
    public final synchronized void join(long millis)
        throws InterruptedException {
            long base = System.currentTimeMillis();
            long now = 0;
    		// 如果小于0抛出异常
            if (millis < 0) {
                throw new IllegalArgumentException("timeout value is negative");
            }
    
    		// 如果还活着,就调用wait
            if (millis == 0) {
                while (isAlive()) {
                    wait(0);
                }
            } else {
                // 如果还活着,还是会调用wait方法
                while (isAlive()) {
                    long delay = millis - now;
                    if (delay <= 0) {
                        break;
                    }
                    wait(delay);
                    now = System.currentTimeMillis() - base;
                }
            }
        }
    

    从源码可以看出,join()方法的底层是用wait()方法实现的,可以看出,join方法是一个同步方法,当主线程调用t1.join()的时候,主线程获得了t1对象的锁,随后进入方法,调用了t1对象的wait方法,使主线程进入了t1对象的等待池,此时,t1线程还在执行,并且后面的t2.start()还没有执行,因此,t2线程还没有开始。等到t1线程执行完毕之后,主线程继续执行,执行了t2.start(),t2线程才会执行。

    因此,可以得出结论,t.join()方法只会使主线程进入等待池并等待t线程执行完毕后才会被唤醒,同时并不影响同一时刻其他正在执行的线程。

    注意:join源码中,只会调用wait方法,并没有在结束时调用notify,这是因为线程在die的时候会自动调用自身的notifyAll方法,来释放所有的资源和锁。

    参考文章链接:
    https://blog.csdn.net/u013425438/article/details/80205693
    
  • 相关阅读:
    MySQL
    Shell运算符:Shell算数运算符、关系运算符、布尔运算符、字符串运算符等
    ps
    top
    sed
    nav响应范围一定要足够宽
    续上获取input的checked用prop时返回的是布尔值
    jq不应该用attr获取input的check值
    jq祖级元素
    一些jquery的坑
  • 原文地址:https://www.cnblogs.com/clover-forever/p/13350669.html
Copyright © 2011-2022 走看看