Join 让执行这个方法的线程插队 ,让当前县城执行完再执行别的线程
package org.famous.unyielding.current.jooin; public class ThreadJoinClient { public static void main(String[] args) { Thread t = new Thread(new Runnable() { @Override public void run() { System.err.println("Hello World"); } }); try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } t.start(); System.err.println("main thread"); } }
加Join 和不加Join的结果就是hello World 输出的顺序不一致。加了Join那么Hello World 会优先执行
Join(Long xx) Sleep(Long xx)的区别 。Join会释放锁,但是Sleep不会
首先验证Join(Long xx)的方法 第二证明Join锁机制:
package org.famous.unyielding.current.jooin; public class ThreadJoinClient { public static void main(String[] args) { Thread t = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } System.err.println("Hello World"); } }); t.start(); try { t.join(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.err.println("main thread"); } }
必须先Start再Join 否则无效。!这点详细见join的源码:
- if (millis == 0) {
- while (isAlive()) {
- wait(0);
- }
- } else {
join的锁机制:
上面的代码中得看是谁调用了join 是主线程 所以停止的是主线程。
本质问题:join(1000)和sleep(1000)的区别是什么。让子线程Join 或者让主线程sleep 本质上都可以达到我们的要求。只要我们预估好时间。
但是如果不加时间呢。还是为了验证锁的问题。
就是join 会不会让调用它的线程释放锁。
1.join 的参数并不是一直等待到指定的时间,如果线程提前运行完成之后还是会提前结束等待的
2.
public class MyTest { public static void main(String[] args) { SonRun sonRun = new SonRun(); Thread thread = new Thread(new JoinRunn(sonRun)); thread.start(); Thread thread2 = new Thread(new ThreeRrun(sonRun)); thread2.start(); } } // 我调用join 会释放锁吗 class JoinRunn implements Runnable { private SonRun sonrun; public JoinRunn(SonRun sonrun) { super(); this.sonrun = sonrun; } @Override public void run() { synchronized (sonrun) { System.err.println("join run get the sonrun lock"); try { sonrun.start(); /*** zhongdian **/ // sonrun.join(3000); Thread.sleep(3000); System.err.println("join run will execute after SonRun"); for (int i = 0; i < Integer.MAX_VALUE; i++) { String newString = new String(); Math.random(); } } catch (InterruptedException e) { e.printStackTrace(); } } } } class SonRun extends Thread { @Override public void run() { Long begin = System.currentTimeMillis(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } Long end = System.currentTimeMillis(); System.err.println(begin - end); } } class ThreeRrun implements Runnable { private SonRun sonrun; public ThreeRrun(SonRun sonrun) { this.sonrun = sonrun; } @Override public void run() { synchronized (sonrun) { System.err.println("what the time shold i fucked be execute"); } } }
这个代码的运行结果在JoinRunn的
// sonrun.join(3000);
Thread.sleep(3000);
分别运行结果是不同的。所以得警惕Join 是会释放锁这个问题的。
join()
If any executing thread t1 calls join()
on t2 i.e; t2.join()
immediately t1 will enter into waiting state until t2 completes its execution. t1调用了t2的join方法,那么t1就会先wait 直到时间结束或者t1运行结束。既然是wait,那么同步的或者加锁的究竟是哪个地方??
yield()
join()
sleep()
yield()
method pauses the currently executing thread temporarily for giving a chance to the remaining waiting threads of the same priority to execute. If there is no waiting thread or all the waiting threads have a lower priority then the same thread will continue its execution. The yielded thread when it will get the chance for execution is decided by the thread scheduler whose behavior is vendor dependent.sleep()
Based on our requirement we can make a thread to be in sleeping state for a specified period of time (hope not much explanation required for our favorite method).
下面关于Yield的
package org.famous.unyielding.current.jooin; public class YieldThreadClient { public static void main(String[] args) { Thread thread1 = new Thread(new YieldRunn()); Thread thread2 = new Thread(new YieldRunn()); thread1.start(); thread2.start(); } } class YieldRunn implements Runnable { @Override public void run() { for (int i = 0; i < 130; i++) { System.err.println(i); if (i == 30) { Thread.yield(); } } } }
时间: 2024-10-10 15:25:08