A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 崔朋朋 中级黑马   /  2012-9-6 12:26  /  2056 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 崔朋朋 于 2012-9-9 17:15 编辑

现在有 线程a 和 线程b     
线程b的run()方法如下:
run(){
...
a.join();
...
}

问题:
当执行完a.join();后是线程a“加入"到b的尾部?还是线程b"加入"到a的尾部?
接下来是执行线程b的run方法?还是执行线程a的run方法?

评分

参与人数 1技术分 +1 收起 理由
王德升 + 1 新生报到,顶一个,!!!

查看全部评分

8 个回复

倒序浏览
楼上说反了吧,当执行到a.join()时,b线程停止,执行线程a的run方法
回复 使用道具 举报
首先要使用join方法,得有两个以上的线程,如果就一个线程,它调用自己的join方法阻塞自己,没有意义!
假如连个线程A和线程B
那么肯定是线程A里调用了B线程的join方法,或者线程B里调用了A线程的join方法
如果是A线程调用B线程的join方法的话,那就是这样的:
class A extends Thread{
public void run(){
  ...
  new B().join();  //查看API( join方法的解释是:--等待该线程终止。),这句话的意思就是:B线程调用join方法,那么就等待B线程终止,也就是等着B执行完
}
}
回复 使用道具 举报
当前线程暂停,等待加入的线程运行结束,当前线程继续执行。
是b线程暂停,等a线程运行完之后,b线程继续执行
class Test {

public static void main(String[] args) {
  final Thread t1 = new Thread(){
   public void run() {
    for (int i = 1; i <= 5; i++) {
     System.out.println("A " + i);
     try {
      Thread.sleep(1000);   
     } catch(Exception e) {
      e.printStackTrace();
     }
    }
   }
  };
  
  Thread t2 = new Thread(){
   public void run() {
    for (int i = 1; i <= 5; i++) {
     System.out.println("B " + i);
     try {
      Thread.sleep(1000);   
      if (i == 2)
       t1.join();   // 当前线程暂停, 等待t1线程执行结束之后再继续
     } catch(Exception e) {
      e.printStackTrace();
     }
    }
   }
  };
  
  t1.start();
  t2.start();
}

}

评分

参与人数 1技术分 +1 收起 理由
王德升 + 1 赞一个!

查看全部评分

回复 使用道具 举报
杨锦 发表于 2012-9-6 13:46
当前线程暂停,等待加入的线程运行结束,当前线程继续执行。
是b线程暂停,等a线程运行完之后,b线程继续执 ...

嗯   明白
a.join();   执行完毕后.   
执行join()线程的run()方法,join线程的run()方法执行完毕后,在执行当前线程
:handshake
回复 使用道具 举报
当b线程执行到a.join();时,b线程就会暂时停止运行,此时就执行a线程中的run()方法.必须要等到a线程彻底彻底执行结束时(也就是说a线程的run()方法的代码执行到末尾),b线程才可以继续执行.当a线程结束后,a线程就不存在了,a线程所占用的空间就被释放了,所以不存在"谁加入谁尾部"的说法.
回复 使用道具 举报
本帖最后由 任艳旭 于 2012-9-7 14:51 编辑

执行a.join()方法,当前线程暂停,也就是线程b,这时候开始运行线程a,执行线程a的run()方法体。线程a的run()方法运行完后,线程b接着运行,向下执行语句。
举个例子:
下面创建两个线程
class ThreadDemo {
        
        public static void main(String[] args) {
                final Thread t1 = new Thread(){
                        public void run() {
                                for (int i = 1; i <= 5; i++) {
                                        System.out.println("A " + i);
                                        try {
                                                Thread.sleep(1000);  //线程t1休眠一秒,线程t2开始      
                                        } catch(Exception e) {
                                                e.printStackTrace();        
                                        }
                                }
                        }        
                };
               
                Thread t2 = new Thread(){
                        public void run() {
                                for (int i = 1; i <= 5; i++) {
                                        System.out.println("B " + i);
                                        try {
                                                Thread.sleep(1000);                //线程t2开始休眠                     
                                                if (i == 2)                              //判断如果i=2的时候,那么就执行下面一句
                                                        t1.join();                        // 当前线程暂停, 等待t1线程执行结束之后再继续
                                        } catch(Exception e) {
                                                e.printStackTrace();        
                                        }
                                }
                        }        
                };
               
                t1.start();
                t2.start();
        }        
        
}
运行结果是这样的:
A 1
B 1
B 2
A 2
A 3
A 4
A 5
B 3
B 4
B 5
回复 使用道具 举报
本帖最后由 陈振兴 于 2012-9-9 03:39 编辑

来个最简单的例子:也是我那个提交测试题当中的
/**
* 模拟妈妈做饭,做饭时发现没有盐了,让儿子去买盐(假设买盐需要3分钟),只有盐买回来之后,妈妈才能继续做饭的过程。
* @author xinglefly
* @version 1
*/
class Mother implements Runnable{
        public void run(){
                System.out.println("妈妈准备做午饭了");
                System.out.println("妈妈发现盐用完了,让儿子去买盐");
                //创建儿子的线程
                Thread son = new Thread(new Son());
                //开启线程
                son.start();
                System.out.println("妈妈等儿子回来");
                try{
                        //等待线程终止
                        son.join();
                }catch(InterruptedException e){
                        //标准错误输出流
                        System.err.print("儿子出事了");
                        System.err.print("妈妈做饭中断");
                        //非0状态异常终止java虚拟机
                        System.exit(1);
                }
                System.out.println("妈妈开始做饭");
                System.out.println("妈妈煮好了饭");
        }
}
class Son implements Runnable{
        public void run(){
                System.out.println("儿子出去买盐");
                System.out.println("买盐需要3分钟");
                try{
                        for(int i=0;i<=3;i++){
                                Thread.sleep(1000*60*3);
                                System.out.println(i+"分钟");
                        }
                }catch(InterruptedException e){
                        System.out.println("儿子发生意外");
                }
                System.out.println("儿子买盐完事");
        }
}
public class Test10 {

        public static void main(String[] args){
                new Thread(new Mother()).start();
        }
}
这样对join的印象会更深刻!执行的顺序就是这样!你在看楼上的文字叙述会舒服很多!

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马