`
cheer_nice
  • 浏览: 99498 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

多线程 之 Join

    博客分类:
  • j2se
阅读更多
一个线程可以在其他线程上调用join()方法,效果是等待一段时间指导第二个线程结束才继续进行。如果某个线程在另一个线程t上调用t.join(),此线程被挂起,直到目标线程t结束才恢复,即t.isAlive()返回为false。
也可以在join()上加一个时间参数,是一个等待的时间上线。
此外 join方法可以被中断 在调用线程上调用interrupt()方法,thinking in java 670有例子。


run() 和start() 是大家都很熟悉的两个方法。把希望并行处理的代码都放在run() 中;stat() 用于自动调用run(),这是JAVA的内在机制规定的。并且run() 的访问控制符必须是public,返回值必须是void(这种说法不准确,run() 没有返回值),run()不带参数。

闲话少说,我们要讲的是join(),我们首先来看个例子:
/**
* @author QingHe
* Creation on 2005-12-19
*/

public class ThreadTest implements Runnable {
public static int a = 0;

public void run() {
for (int k = 0; k < 5; k++) {
a = a + 1;
}
}

public static void main(String[] args) throws Exception {
Runnable r = new ThreadTest();
Thread t = new Thread(r);
t.start();
System.out.println(a);
}
}



请问程序的输出结果是5吗?答案是:有可能。其实你很难遇到输出5的时候,通常情况下都不是5。当然这也和机器有严重的关系。为什么呢?我的解释是当主线程main方法执行System.out.println(a);这条语句时,线程还没有真正开始运行,或许正在为它分配资源准备运行吧。因为为线程分配资源需要时间,而main方法执行完t.start()方法后继续往下执行System.out.println(a);,这个时候得到的结果是a还没有被改变的值0。怎样才能让输出结果为5!其实很简单,join() 方法提供了这种功能。join() 方法,它能够使调用该方法的线程在此之前执行完毕。

/**
* @author QingHe
* Creation on 2005-12-19
*/

public class ThreadTest implements Runnable {
public static int a = 0;

public void run() {
for (int k = 0; k < 5; k++) {
a = a + 1;
}
}

public static void main(String[] args) throws Exception {
Runnable r = new ThreadTest();
Thread t = new Thread(r);
t.start();
t.join();
System.out.println(a);
}
}



这个时候,程序输入结果始终为5。

为了证明如果不使用t.join()方法,主线程main方法的System.out.println(a);语句将抢先执行,我们可以在main方法中加入一个循环,这个循环用来延长main方法执行的时间,循环次数将严重取决于机器性能。如果循环次数得当,我们也可以看到a的输出结果是5。
/**
* @author QingHe
* Creation on 2005-12-19
*/

public class ThreadTest implements Runnable {
public static int a = 0;

public void run() {
for (int k=0; k<5; k++) {
a = a + 1;
}
}

public static void main(String[] args) throws Exception {
Runnable r = new ThreadTest();
Thread t = new Thread(r);
t.start();
for (int i=0; i<300; i++) {
/*
 注意循环体内一定要有实际执行语句,否则编译器或JVM可能优化掉你的这段代码,视这段代
 码为无效。             
*/
System.out.print(i);
}
System.out.println();
System.out.println(a);
}
}



在上面的例子中多次使用到了Thread类的join方法。我想大家可能已经猜出来join方法的功能是什么了。对,join方法的功能就是使异步执行的线程变成同步执行。也就是说,当调用线程实例的start方法后,这个方法会立即返回,如果在调用start方法后后需要使用一个由这个线程计算得到的值,就必须使用join方法。如果不使用join方法,就不能保证当执行到start方法后面的某条语句时,这个线程一定会执行完。而使用join方法后,直到这个线程退出,程序才会往下执行。下面的代码演示了join的用法。
public class JoinThread extends Thread
{
    public static volatile int n = 0;

    public void run()
    {
        for (int i = 0; i < 10; i++, n++)
            try
            {
                sleep(3);  // 为了使运行结果更随机,延迟3毫秒
            }
            catch (Exception e)
            {
            }                                      
    }
    public static void main(String[] args) throws Exception
    {
        Thread threads[] = new Thread[100];
        for (int i = 0; i < threads.length; i++)  // 建立100个线程
            threads[i] = new JoinThread();
        for (int i = 0; i < threads.length; i++)   // 运行刚才建立的100个线程
            threads[i].start();
        if (args.length > 0)  
            for (int i = 0; i < threads.length; i++)   // 100个线程都执行完后继续
                threads[i].join();
        System.out.println("n=" + JoinThread.n);
    }
}





在例程2-8中建立了100个线程,每个线程使静态变量n增加10。如果在这100个线程都执行完后输出n,这个n值应该是1000。

1.测试1

使用如下的命令运行上面程序:

java mythread.JoinThread

程序的运行结果如下:

n=442

这个运行结果可能在不同的运行环境下有一些差异,但一般n不会等于1000。从上面的结果可以肯定,这100个线程并未都执行完就将n输出了。

2. 测试2

使用如下的命令运行上面的代码:

在上面的命令行中有一个参数join,其实在命令行中可以使用任何参数,只要有一个参数就可以,这里使用join,只是为了表明要使用join方法使这100个线程同步执行。

程序的运行结果如下:

n=1000

无论在什么样的运行环境下运行上面的命令,都会得到相同的结果:n=1000。这充分说明了这100个线程肯定是都执行完了,因此,n一定会等于1000。




分享到:
评论

相关推荐

    Python threading 3 join功能 (多线程 教学教程tutorial)

    Python_threading_3_join功能_(多线程_教学教程tutorial)

    Linux下的多线程编程.pdf

    LinuxThreads 库提供了一些多线程编程的关键函数,如 pthread_create() 函数、pthread_exit() 函数、pthread_join() 函数等。这些函数可以帮助开发人员轻松地编写多线程程序。 多线程编程是一种高效的程序设计方法...

    深入浅出 Java 多线程.pdf

    在本文中,我们将深入浅出Java多线程编程的世界,探索多线程编程的基本概念、多线程编程的优点、多线程编程的缺点、多线程编程的应用场景、多线程编程的实现方法等内容。 一、多线程编程的基本概念 多线程编程是指...

    【IT十八掌徐培成】Java基础第08天-02.多线程-join-daemon-同步.zip

    【IT十八掌徐培成】Java基础第08天-02.多线程-join-daemon-同步.zip

    嵌入式软件开发技术:第5章 嵌入式Linux多线程编程.ppt

    嵌入式Linux多线程编程 嵌入式Linux多线程编程是嵌入式系统开发中的一种重要技术,能够提高系统的效率和响应速度。本章节将详细介绍嵌入式Linux多线程编程的基本概念、线程的创建、同步和互斥、线程属性、多线程...

    perl实现多线程详解[整理].pdf

    Perl 多线程实现详解 Perl 是一种功能强大的高级编程语言,它提供了多种方法来实现多线程编程。多线程编程是指在同一个进程中同时运行多个线程,以提高程序的执行效率和响应速度。Perl 语言提供了多种多线程实现...

    对python 多线程中的守护线程与join的用法详解

    多线程:在同一个时间做多件事 守护线程:如果在程序中将子线程设置为守护线程,则该子线程会在主线程结束时自动退出,设置方式为thread.setDaemon(True),要在thread.start()之前设置,默认是false的,也就是主线程...

    多线程机制

    7、 浅析 Java Thread.join() : java多线程实现主线程等待所有子线程执行完毕 16 8、 线程运行中抛出异常的处理 19 9、 Callable 有返回值的线程 20 10、 Callable结合FutureTask的多线程使用(免打扰模式) 24

    python 多线程中join()的作用

    温习python 多进程语法的时候,对 join的理解不是很透彻,本文通过代码实践来加深对 join()的认识。 multiprocessing 是python提供的跨平台版本的多进程模块。multiprocessing可以充分利用多核,提升程序运行效率。...

    分而治之,ForkJoin,多线程编程

    分而治之,ForkJoin,多线程编程

    Linux多线程编程入门[参照].pdf

    一个简单的多线程程序example1.c的编写过程中,需要include头文件stdio.h和pthread.h,使用pthread_create函数创建一个新的线程,pthread_join函数等待线程的结束。编译时需要使用-lpthread选项,连接pthread库。

    多线程实验_1

    C#多线程实验,就AutoResetEvent,ManualResetEvent,Thread.join(),委托多线程回调。

    VB.NET多线程编程的详细说明(完整版)[定义].pdf

    "VB.NET多线程编程的详细说明" 本文详细介绍了VB.NET多线程编程的概念、优点和实现方法。多线程编程可以提高应用程序的性能和响应速度,但同时也需要注意线程的管理和同步。 多线程编程的概念 多线程编程是指在一...

    C#多线程之Thread中Thread.Join()函数用法分析

    主要介绍了C#多线程之Thread中Thread.Join()函数用法,实例分析了Thread.Join()方法的原理与使用技巧,非常具有实用价值,需要的朋友可以参考下

    Linux系统下基于Tcp的多线程大文件上传实现.pdf

    Linux系统下基于Tcp的多线程大文件上传实现.pdf 本文介绍了一种基于Tcp的多线程大文件上传实现方法,在Linux系统下实现大文件上传的解决方案。该方法通过将大文件分块,并使用多线程技术来实现文件传输,提高了文件...

    JAVA多线程之方法 JOIN详解及实例代码

    主要介绍了JAVA多线程之方法 JOIN详解及实例代码的相关资料,需要的朋友可以参考下

    多线程相关代码(V3)

    多线程相关的(具体包括Lock synchronized Join ThreadLocal Executors CountDownLatch等)一些demo。

    多线程API.zip

    常见的多线程API和用法 pthread_self函数 pthread_create函数 pthread_exit函数 pthread_join函数 pthread_detach函数 pthread_equal函数

    Java线程中wait,await,sleep,yield,join用法总结.pdf

    Java线程中wait、await、sleep、yield、join用法汇总,文章里面总结了这些关键字的用法,并且里面带有源码帮助分析用法,此一文就可以理解这些关键字用法,推荐拥有

Global site tag (gtag.js) - Google Analytics