`
wandejun1012
  • 浏览: 2719210 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

多线程join怎么用

 
阅读更多

join,说白了就是让本来异步执行的多线程变成同步执行的。

 

这么说比较抽象,不太好理解,我们举个例子如下:

 

package mythread;  
 
public class JoinThread extends Thread  
{  
    public static int n = 0;  
 
    static synchronized void inc()  
    {  
    	
        n++;  
        System.out.println("当前活动线程和N分别为:"+Thread.currentThread().getName()+"_"+n);
    }  
    public void run()  
    {  
        for (int i = 0; i < 10; i++)  
            try 
            {  
                inc(); 
                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();
        	System.out.println("线程"+i+"start了");
        	threads[i].join();//关键点
        }
        	
        System.out.println("n=" + JoinThread.n);  
        }
    
}  

这段代码,放在eclipse中运行一下,看看就会发现其中的端倪了。

 在代码中,我作了个标记“关键点”。

大家可以分别将这句话注释和打开时,发现n输入的值是不一样的。

如果不用join(),那么n打出来每次都不一样,有可能是300,有可能是180,反正不可能是1000。

而加入Join后必然是1000。

那么这是为什么呢?

原来大家要知道线程与线程是竞争的关系,当main函数创建了一个第一个线程后,它就开始和main所在的线程进行竞争(即抢占对CPU的控制权)。谁也不服输。

  如果线程1竞争成功,那么他就是去将n++,他想去循环10遍,可是main不会让它这么轻松,通过观察此程序运行结果就可以看出,线程1的10次是被分散了很多次才完成的,毕竟当线程创建越多,线程1的竞争能力就越差。

  如果是main竞争成功,那么他就会去创建线程2,线程2创建成功后,又同时与线程1和main竞争。

  这样当main创建完第100个线程后,此时100个线程正在打架,谁了不服谁。每个线程的10次都没有全部完成。

  此时,如果我们强行打印出N的值,肯定是远远小于1000的。

  而如果我们刚创建完一个线程就让它Join后,那么就相当于有警察在旁边执勤了。

  main线程不准抢线程1的CPU控制权,等线程1运行结束后,再让main创建线程2。

  这样就有条不紊了。

 

分享到:
评论
5 楼 zhangjq5 2012-09-04  
寻墨小楼 写道
zhangjq5 写道
wzt7576 写道
线程1的10次是被分散了很多次才完成的,



你说的这种情况不可能出现吧,当第一个新线程启动后,join后(加入了主线程),主线程必须等他执行完才能执行for循环的下一轮循环(开启第二个新线程)啊

哥们,那时候人家的线程是在没加入join方法的前提下执行的!!!



兄弟看看我3楼的疑问啊。

哥们,你的顺序弄错了:
        thread1.start();   
        thread2.start();   
           
        thread1.join();   
        thread2.join();   

应该改成:
        thread1.start();
        thread1.join();
        thread2.start();
        thread2.join();

其实这里有三个线程,一个是主线程(这里称main),main是开始就存在的,它负责主流程代码的执行,首先创建了线程1和线程2,当线程1和线程2启动以后,程序中就有了三个线程。并且这3个线程同时进行各自的任务。你之前那个顺序是两个线程已经执行完了,然后才去join的,所以没有效果。
4 楼 寻墨小楼 2012-08-29  
zhangjq5 写道
wzt7576 写道
线程1的10次是被分散了很多次才完成的,



你说的这种情况不可能出现吧,当第一个新线程启动后,join后(加入了主线程),主线程必须等他执行完才能执行for循环的下一轮循环(开启第二个新线程)啊

哥们,那时候人家的线程是在没加入join方法的前提下执行的!!!



兄弟看看我3楼的疑问啊。
3 楼 寻墨小楼 2012-08-29  
我也有这个简单的疑问。

譬如这个简单的join测试用例。

public class EvenOdd extends Thread{

	private int i0, delay; 
	
	public EvenOdd(int first, int interval){
		i0 = first; delay = interval;
	}
	
	public void run(){
		try{
			for(int i=i0; i<= 100; i+=2){
	           System.out.println(i);
	           sleep(delay);
			}
			
		} catch(InterruptedException e){
			return;
		}
	}
}

public class ThreadTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) 
	             throws InterruptedException {
		// TODO Auto-generated method stub
        EvenOdd thread1 = new EvenOdd(1, 20);
        EvenOdd thread2 = new EvenOdd(0, 30);
        
        thread1.start();
        thread2.start();
        
        thread1.join();
        thread2.join();
        
        System.out.println("Main thread done");
	}

}


是thread1先join到主线程 然后thread2才开始join进去。
但结果是thread1, thread2两个交替进行的。
按我的理解,先执行完thread1, 然后再执行thread2,最后主线程。
但现在是thread1, thread2交替执行,然后是主线程。
求解?
2 楼 zhangjq5 2012-08-29  
wzt7576 写道
线程1的10次是被分散了很多次才完成的,



你说的这种情况不可能出现吧,当第一个新线程启动后,join后(加入了主线程),主线程必须等他执行完才能执行for循环的下一轮循环(开启第二个新线程)啊

哥们,那时候人家的线程是在没加入join方法的前提下执行的!!!
1 楼 wzt7576 2012-06-04  
线程1的10次是被分散了很多次才完成的,



你说的这种情况不可能出现吧,当第一个新线程启动后,join后(加入了主线程),主线程必须等他执行完才能执行for循环的下一轮循环(开启第二个新线程)啊

相关推荐

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

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

    多线程测试(是多线程的测试,对学习多线程的朋友有用)

    3. 资源消耗测试:分析多线程运行时内存、CPU和其他资源的使用情况。 4. 并发测试:评估程序在高并发场景下的稳定性和响应能力。 5. 错误处理和异常测试:确保在多线程环境下程序能够正确捕获和处理异常。 总之,多...

    多线程例子 演示多线程使用

    在计算机编程中,多线程是一种并发执行任务的技术,它允许多个子任务在同一时间运行,从而提高了程序的效率和响应性。这个“多线程例子”演示了如何在C++环境中实现多线程功能。下面我们将深入探讨多线程的基本概念...

    PB多线程实现

    在PB9中,虽然官方并未直接支持多线程,但开发者可以通过使用Windows API函数来实现。一种常见的方式是创建一个新的窗口类,该窗口类在不同的线程上运行。通过调用如CreateThread或BeginThread等API函数,可以在新的...

    Linux下C语言多线程编程实例

    在 Linux 下,多线程编程使用的是 POSIX 规范,提供了很多有用的函数和变量来控制线程的创建、执行和同步。 pthread 库是 Linux 下多线程编程的核心库,提供了丰富的函数和变量来控制线程的创建、执行和同步。 在本...

    c++多线程编程的十个例子

    在C++编程中,多线程技术是一种强大的工具,它允许程序同时执行多个任务,从而提高了效率和响应性。以下是对“C++多线程编程的十个例子”的详细讲解,这些例子将帮助你在Windows环境下深入理解和应用多线程。 1. **...

    C# 多线程实例多线程实例多线程实例

    在编程领域,多线程是实现并发执行任务的关键技术,特别是在C#这样的语言中,它提供了丰富的多线程支持。本文将深入探讨C#中的多线程实例,以帮助开发者理解如何有效地利用多核处理器资源,提高程序的执行效率。 多...

    演示PB如何实现多线程

    在PowerBuilder(PB)开发环境中,多线程技术是一种关键特性,它允许应用程序同时执行多个独立的任务,提高程序...在实际应用中,开发者应根据需求设计复杂的多线程逻辑,合理使用同步机制,以确保程序的稳定性和性能。

    C#.NET多线程实例6个(包括多线程基本使用,多线程互斥等全部多线程使用实例)完整源码

    本资源包含六个完整的多线程实例,涵盖了从基础使用到高级特性的全面实践,例如线程的创建、同步与互斥。 1. **线程的创建**:在C#.NET中,可以使用`System.Threading.Thread`类来创建新的线程。实例可能演示了如何...

    深入浅出 Java 多线程.pdf

    3.使用线程池:可以使用线程池来实现多线程编程,以提高程序的执行效率和响应速度。 多线程编程是一个非常重要的概念,它可以提高程序的执行效率和响应速度。但是,多线程编程也有一些缺点和挑战,需要程序员小心地...

    Linux系统下的多线程编程入门.pdf

    多线程编程需考虑性能优化,包括减少上下文切换、合理分配工作负载、使用合适的同步机制等。调试多线程程序通常较复杂,gdb等调试器提供了线程查看和控制功能,帮助开发者定位问题。 总结,Linux系统的多线程编程为...

    C#.NET多线程实例6个(包括多线程基本使用,多线程互斥等全部多线程使用实例).rar

    这个压缩包包含六个C#.NET多线程的实例,涵盖了多线程的基本使用以及互斥等高级特性。以下是这些实例可能涉及的知识点详解: 1. **线程创建与启动** - `System.Threading.Thread` 类是.NET中创建新线程的基础,...

    C#多线程排序例子

    同时,也应考虑线程间的通信开销以及上下文切换的成本,以确保多线程的使用确实带来了性能提升。 在实际应用中,理解并熟练运用这些知识点,可以有效地编写出高效的多线程排序程序,充分利用现代计算机的多核处理...

    CC++多线程编程练习题大全

    2. **线程同步与互斥**:为避免多线程间的竞态条件,需要使用同步机制。C++提供了`std::mutex`来实现互斥锁,保证同一时间只有一个线程访问共享资源。`std::lock_guard`是RAII(Resource Acquisition Is ...

    可并行递归算法的递归多线程实现

    Java作为一门广泛使用的高级编程语言,其内置的多线程机制为开发者提供了丰富的工具,以便在多核架构上进行高效编程。在递归算法中,利用Java的多线程特性可以显著提升算法的执行效率,尤其是在处理大规模数据集时。...

    C++在多线程中使用mciSendString播放音乐demoB

    本示例"C++在多线程中使用mciSendString播放音乐demoB"着重于如何在多线程环境下利用Windows Multimedia Control Interface (MCI) 函数mciSendString来实现音乐播放。下面我们将深入探讨这两个关键概念。 首先,多...

    python selenium chrome 多开 多线程

    本主题聚焦于如何使用Python的Selenium与Chrome浏览器进行多开和多线程操作,结合phantomjs和chromedriver这两个关键组件来实现。首先,让我们详细了解一下这些概念。 1. **Selenium**: Selenium是一个强大的Web...

    linux多线程编程.pdf

    本文档主要涉及Linux多线程编程的一些关键知识点,包括pthread线程库的使用、线程的创建、线程的退出以及线程的同步等。 首先,我们来探讨pthread线程库。pthread,全称POSIX threads,是遵循POSIX线程标准的一套...

    java多线程Demo

    在多线程环境下,如果一个变量被多个线程共享且只进行读写操作,可以使用volatile保证数据的一致性。 9. sleep(), yield(), interrupt(): - sleep()方法使当前线程暂停指定的时间,然后继续执行。 - yield()方法...

    java多线程经典案例

    通过分析并实践`threadTest`案例,我们可以深入理解Java多线程的原理和使用技巧,为编写高效并发程序打下坚实基础。同时,也要注意多线程编程中的死锁、活锁和饥饿等问题,合理设计线程间的交互,避免出现不可预期的...

Global site tag (gtag.js) - Google Analytics