/* 和主线程竞争 */ public class Test04 { static int ticket = 100; public static void main(String[] args) { new Thread(()->{ while(ticket>0){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (Test04.class) { System.out.println("子线程:" + ticket--); } } }).start(); while(ticket>0){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (Test04.class) { System.out.println("主线程:" + ticket--); } } } }
这个是没有使用join方法,正常竞争。
使用thread.join()
我们需要注意的时,在我们调用thread.join(0方法时,此时已经切换到主线程了,并不是在子线程中执行,在子线程中执行的只有run()方法
如果简单理解,那么就是在主线程中调用了thread.join(0方法,这个方法有一个判断:如果当前线程(这里指的是实例对象,就是synchronized表示的this对象thread)存活,那么join()方法,也就是在主线程中调用的join()方法会调用thread.wait()方法进入阻塞状态,导致主线程也会进入阻塞状态
如下图:子线程thread.wait()并不会影响子线程的执行,但是却会导致自身方法进入阻塞,直到子线程结束,才会跳出while循环,执行主线程,同理我们在其他线程中调用某个线程的thread.join()方法也会导致自身线程进入阻塞
public final synchronized void join(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } }