我是靠谱客的博主 美丽小熊猫,最近开发中收集的这篇文章主要介绍多线程——join()、sleep(),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Thread类的方法中有一个join()方法,它是普通的实例方法,根据Java api,该方法有如下三种形式:

void join(): Waits for this thread to die.
void join(long millis): Waits at most millis milliseconds for this thread to die.
void join(long millis, int nanos): Waits at most millis milliseconds plus nanos nanoseconds for this thread to die.

该方法的作用是“等待该线程终止”,一直等待,直到程终止,而带参数的方法的作用是“ 等待该线程终止,至多等待多少毫秒数 (或毫秒数+纳秒数)”。

在此之前,我对这个方法一直有两个疑问,困惑不解:

  1. 为什么这个方法的作用是等待该线程终止,为什么它的名字是“加入”的意思?
  2. 在这个等待的关系中,到底是谁等待谁?

在看了很多人的博客、看了这个方法的源码、看了《Java多线程编程核心技术》这本书和实践之后,我的理解如下,作为自我学习总结。


1. 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;
            }
        }
    }

join(long millis)方法的源代码如上所示,首先该方式是synchronized,其次它的实现原理是调用了wait()方法。

2. join()/wait()与sleep()的区别

由上,所以join()和sleep()这两个方法的区别,本质上是wait()和sleep()这两个方法的区别。

wait()和sleep()的区别:

  • 这两个方法来自不同的类,wait()方法来自Object类,sleep()方法来自Thread类;
  • wait()方法有三种形式:wait()、wait(long timeout)、wait(long timeout, int nanos),而sleep()方法两种形式:sleep(long millis)、sleep(long millis, int nanos),即sleep()方法没有无参形式。其次,sleep()方法是静态方法。
  • 其实区别主要还是来自于这两个方法对同步的处理上:wait()方法会释放锁,sleep()方法不释放锁。在sleep()方法的源代码中有这样一句话:

The thread does not lose ownership of any monitors.

所以join()和sleep()这两个方法的区别,来自于它们对同步的处理上,如上第三条。

3. join()的作用分析

join()方法具有使线程依次串行执行的作用,也就是使线程排队运行。对于t.join()语句,其中的等待关系如下:
join()方法的作用是使线程t正常执行run()方法中的任务,而使当前线程s一直等待线程t终止,
在很多情况下,主线程生成并起动了子线程,所以线程s有可能是主线程,也有可能是其它子线程。
也就是t.join()方法后面的代码,只有等到t线程结束了才能执行。join()方法的使用方式是在线程t启动后直接调用。

代码实例:

功能:三个线程,一个打印A,一个打印B,一个打印C,打印出6个连续的ABC。

/*
 * 三个线程, 一个打印A, 一个打印B, 一个打印C, 打印出6个连续的ABC.
 */
public class PrintABC implements Runnable {
    @Override
    public void run() {
        if(Thread.currentThread().getName().equals("A")){
                System.out.print("A");
        }
        if(Thread.currentThread().getName().equals("B")){
                System.out.print("B");
        }
        if(Thread.currentThread().getName().equals("C")){
                System.out.print("C");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        for(int i=0; i<6; i++){
            PrintABC r = new PrintABC();
            Thread A = new Thread(r, "A");
            A.start();
            A.join();
            Thread B = new Thread(r, "B");
            B.start();
            B.join();
            Thread C = new Thread(r, "C");
            C.start();
            C.join();
        }
    }
}

运行结果:

这里写图片描述

嘻嘻~

这里写图片描述

最后

以上就是美丽小熊猫为你收集整理的多线程——join()、sleep()的全部内容,希望文章能够帮你解决多线程——join()、sleep()所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部