java 多线程join,合并线程

[seriesposts sid=500]
线程的join合并的含义就是将几个并行线程的线程合并为一个单线程执行,应用场景是当一个线程必须等待另一个线程执行完毕才能执行时可以使用join方法。

package com.javaer.thread;
 
public class Tjoin {
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Thread t = new Thread(new Runner());
        t.start();
        try {
            t.join(1000);
            System.out.println("join ok");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
 
        }
 
	}
 
}
 
class Runner implements Runnable {
 
    @Override
    public void run() {
        try {
            System.out.println("Start sleep");
            Thread.sleep(1000);
           System.out.println("End sleep");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
 
    }
}
Start sleep
join ok
End sleep

主线程等待1000ms,进行合并,跳回主线程,然后执行子线程

如果将

t.join(1000);

改为

t.join(2000);

主线程等待2000ms,进行合并。

结果

Start sleep
End sleep
join ok

主线程等2000,开始join。 跳回主线程,发现子线程都执行完毕了。

如果改成

t.join(0)

JDK这样说的 A timeout of 0 means to wait forever 字面意思是永远等待.

结果

Start sleep
End sleep
join ok

其实Join方法实现是通过wait。 当main线程调用t.join时候,main线程会获得线程对象t的锁(wait 意味着拿到该对象的锁),调用该对象的wait(等待时间),直到该对象唤醒main线程,比如退出后。

所以上面的t.join(0) 等到子线程退出以后,跳回主线程。

main 线程调用t.join时,必须能够拿到线程t对象的锁,如果拿不到它是无法wait的,刚开的例子t.join(1000)不是说明了main线程等待1秒,如果在它等待之前,其他线程获取了t对象的锁,它等待时间可不就是1秒了

 
package com.javaer.thread;
 
public class Tjoin {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Thread t = new Thread(new Runner());
		new Threader(t).start();
		t.start();
		try {
			t.join(1000);
			System.out.println("join ok");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
 
class Threader extends Thread {
	Thread thread;
	public Threader(Thread thread) {
		this.thread = thread;
	}
	@Override
	public void run() {
		holdThreadLock();
	}
	public void holdThreadLock() {
		synchronized (thread) {
			System.out.println("获取一个锁");
			try {
				Thread.sleep(9000);
			} catch (InterruptedException ex) {
				ex.printStackTrace();
			}
			System.out.println("释放锁");
		}
	}
}
 
class Runner implements Runnable {
 
	@Override
	public void run() {
		try {
			System.out.println("Start sleep");
			Thread.sleep(2000);
			System.out.println("End sleep");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
获取一个锁
Start sleep
End sleep
释放锁
join ok

一个线程获取了锁,主线在join的时候,即使被join的线程结束了,因为线程被锁住,所以即使join的时间也到了,但是还是必须等待锁释放,才能被join


This entry was posted in JAVA and tagged , , , . Bookmark the permalink.
月小升QQ 2651044202, 技术交流QQ群 178491360
首发地址:月小升博客https://java-er.com/blog/java-thread-join/
无特殊说明,文章均为月小升原创,欢迎转载,转载请注明本文地址,谢谢
您的评论是我写作的动力.
2020.03.24 评论已经全局关闭,有事加QQ聊天