• join()方法的源码分析


    /*
    和主线程竞争
     */
    public class Test04 {
        static int ticket = 100;
        public static void main(String[] args) {
            new Thread(()->{
                while(ticket>0){
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (Test04.class) {
    
                        System.out.println("子线程:" + ticket--);
                    }
                }
            }).start();
            while(ticket>0){
                try {
                    Thread.sleep(10);
    
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (Test04.class) {
    
                    System.out.println("主线程:" + ticket--);
                }
            }
        }
    }

    这个是没有使用join方法,正常竞争。

     使用thread.join()

     我们需要注意的时,在我们调用thread.join(0方法时,此时已经切换到主线程了,并不是在子线程中执行,在子线程中执行的只有run()方法

    如果简单理解,那么就是在主线程中调用了thread.join(0方法,这个方法有一个判断:如果当前线程(这里指的是实例对象,就是synchronized表示的this对象thread)存活,那么join()方法,也就是在主线程中调用的join()方法会调用thread.wait()方法进入阻塞状态,导致主线程也会进入阻塞状态

    如下图:子线程thread.wait()并不会影响子线程的执行,但是却会导致自身方法进入阻塞,直到子线程结束,才会跳出while循环,执行主线程,同理我们在其他线程中调用某个线程的thread.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;
                }
            }
        }

  • 相关阅读:
    python加载csv数据
    Android项目依赖库管理方式简介
    Android PhotoView基本功能实现
    Android ListView的header footer设置visibility gone不起作用
    [干货][EMIT]千行代码实现代理式AOP+属性的自动装配
    Emit实现DataRow转化成强类型的T
    有关docker新版的icc、iptables的一个巨坑
    Mac神器Iterm2的Shell Integration的用法和注意事项
    生成ssl证书文件
    python3 module中__init__.py的需要注意的地方
  • 原文地址:https://www.cnblogs.com/guosai1500581464/p/13394784.html
Copyright © 2020-2023  润新知