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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© ò壞尛孩 中级黑马   /  2014-4-12 14:41  /  1668 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. class Demo
  2. {
  3. ...
  4. }
  5. class JoinDemo
  6. {
  7. public static void main(String[] args)
  8. {
  9. Demo d=new Demo();
  10. Thread t1=new Thread(d);
  11. Thread t2=new Thread(d);

  12. t1.start();
  13. t2.start();
  14. <b>t1.join();//这里执行的线程有三个t1,t2,main为什么t1线程join下后抢夺的是main线程的执行权,而不是t2或者是t2和main的执行权,</b>
复制代码

评分

参与人数 1技术分 +1 收起 理由
何伟超 + 1

查看全部评分

8 个回复

倒序浏览
其实很简单:thread.Join把指定的线程加入到当前线程。
而线程t1是由主线程main生成并起动,主线程main才是线程t1的当前线程。
主线程main中调用了线程t1的Join()方法,直到线程t1执行完毕后,才会继续执行线程main

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1

查看全部评分

回复 使用道具 举报
首先要理解join()的作用,join()方法的作用就是让一个线程强制运行,线程运行期间,被抢夺线程是无法运行的,必须等待此线程完成后才可以继续执行。
修改测试代码如下:
  1. class Demo implements Runnable
  2. {

  3.         @Override
  4.         public void run() {
  5.                 for(int i=0; i<50; i++) {
  6.                         System.out.println(Thread.currentThread().getName() + " --> Demo" + i);
  7.                 }
  8.         }
  9.        
  10. }
  11. public class JoinDemo
  12. {
  13.         public static void main(String[] args)
  14.         {
  15.                 Demo d = new Demo() ;
  16.                 Thread t1=new Thread(d);
  17.                 t1.setName("t1");                 //设置线程名称
  18.                 Thread t2=new Thread(d);
  19.                 t2.setName("t2");                 //设置线程名称
  20.                
  21.                 t1.start();
  22.                 t2.start();
  23.                
  24.                 for(int i=0; i<50; i++) {
  25.                         if(i>10) {
  26.                                 try {
  27.                                         t1.join();                //线程t1强制执行
  28.                                 } catch (InterruptedException e) {
  29.                                         e.printStackTrace();
  30.                                 }
  31.                         }
  32.                         System.out.println("Main线程 --> " + i);
  33.                 }
  34.         }
  35. }
复制代码

运行结果截图:


从以上程序发现,它抢夺的当前线程。

评分

参与人数 1技术分 +1 收起 理由
菜小徐 + 1

查看全部评分

回复 使用道具 举报
_Water 发表于 2014-4-12 15:00
其实很简单:thread.Join把指定的线程加入到当前线程。
而线程t1是由主线程main生成并起动,主线程main才是 ...

也就是说谁调用这个线程的,就暂停哪个线程的资源是吗?如果在t1线程里面调用t2.join()暂停的就是t1线程是吗?
回复 使用道具 举报
join()的使用是抢夺当前线程的使用权,直到调用join()的线程结束,才执行其他线程。在main()方法中,主线程是main(),所以抢走的是main()的使用权,当t1线程结束后,才又main线程跟t2抢执行权

评分

参与人数 1技术分 +1 收起 理由
ily521125 + 1

查看全部评分

回复 使用道具 举报
ò壞尛孩 发表于 2014-4-12 20:44
也就是说谁调用这个线程的,就暂停哪个线程的资源是吗?如果在t1线程里面调用t2.join()暂停的就是t1线程 ...

比如说在主线程 开启了 三个线程 t1  t2  t3 ,当我们调用t1.join()时,主线程被阻塞   但是 t2  t3 是正常运行的

t1  t2  t3 他们三个 继续争夺 执行权    t1.join()只会阻塞当前线程  对其他线程无影响
回复 使用道具 举报
首先你要知道join()这个方法的作用,它是把指定线程合并到当前线程中,并且指定线程执行完之后当前线程才能接着继续执行。
其次就要知道哪个指定线程,哪个是当前线程。调用join方法的就是指定线程,执行这条语句的线程就是当前线程,你的代码中t1.join(),显然t1是指定线程,而执行t1.join()这条语句的线程是main线程,所以t1线程抢夺下的是main的执行权
回复 使用道具 举报
main主方法其实也是一个线程,可以使用join()方法让一个线程强制运行,线程强制运行期间,其他线程无法运行,在这里,main主方法是一个系统的默认线程,所以t1线程抢夺的是main线程的执行权!
回复 使用道具 举报
join()是Thread类的一个方法。根据jdk文档的定义:
public final void join()throws InterruptedException: Waits for this thread to die.
join()方法的作用,是等待这个线程结束;但显然,这样的定义并不清晰。个人认为"Java 7 Concurrency Cookbook"的定义较为清晰:
join() method suspends the execution of the calling thread until the object called finishes its execution.
也就是说,t.join()方法阻塞调用此方法的线程(calling thread),直到线程t完成,此线程再继续;通常用于在main()主线程内,等待其它线程完成再结束main()主线程。

  1. class Demo implements Runnable
  2. {

  3.         @Override
  4.         public void run() {
  5.                 for(int i=0; i<50; i++) {
  6.                         System.out.println(Thread.currentThread().getName() + " --> Demo" + i);
  7.                 }
  8.         }
  9.         
  10. }
  11. public class JoinDemo
  12. {
  13.         public static void main(String[] args)
  14.         {
  15.                 Demo d = new Demo() ;
  16.                 Thread t1=new Thread(d);
  17.                 t1.setName("t1");                 //设置线程名称
  18.                 Thread t2=new Thread(d);
  19.                 t2.setName("t2");                 //设置线程名称
  20.                
  21.                 t1.start();
  22.                 t2.start();
  23.                
  24.                 for(int i=0; i<50; i++) {
  25.                         if(i>10) {
  26.                                 try {
  27.                                         t1.join();                //线程t1强制执行
  28.                                 } catch (InterruptedException e) {
  29.                                         e.printStackTrace();
  30.                                 }
  31.                         }
  32.                         System.out.println("Main线程 --> " + i);
  33.                 }
  34.         }
  35. }
复制代码
可以看出,Join方法实现是通过wait(小提示:Object 提供的方法)。 当main线程调用t1.join时候,main线程会获得线程对象t1的锁(wait 意味着拿到该对象的锁),调用该对象的wait(等待时间),直到该对象唤醒main线程 ,比如退出后。这就意味着main 线程调用t2.join时,必须能够拿到线程t2对象的锁。


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