场景一:
public class FinancialTest { public static void main(String[] args) { FinancialTest test = new FinancialTest(); Thread t1 = new Thread(new Thread() { @Override public void run() { test.say(); } }, "t1"); Thread t2 = new Thread(new Thread() { @Override public void run() { test.say(); } }, "t2"); Thread t3 = new Thread(new Thread() { @Override public void run() { test.say(); } }, "t3"); t1.start(); t2.start(); t3.start(); } public void say() { for (int i = 0; i < 4; i++) { System.out.println(Thread.currentThread().getName() + ":------------------"); if (i == 3) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } }输出:
t2:------------------
t2:------------------
t2:------------------
t2:------------------
t1:------------------
t3:------------------
t1:------------------
t3:------------------
t1:------------------
t3:------------------
t1:------------------
t3:------------------
t1、t2、t3混乱执行。
场景二:
给say方法添加synchronized关键字
public synchronized void say() { for (int i = 0; i < 4; i++) { System.out.println(Thread.currentThread().getName() + ":------------------"); if (i == 3) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }输出 :
t1:------------------
t1:------------------
t1:------------------
t1:------------------
t3:------------------
t3:------------------
t3:------------------
t3:------------------
t2:------------------
t2:------------------
t2:------------------
t2:------------------
t1 \t2\t3顺序执行,但不能保证是t1先执行还是t2先执行或是t3先执行。
场景三:t1, t2, t3顺序执行
public class FinancialTest { public static void main(String[] args) { FinancialTest test = new FinancialTest(); Thread t1 = new Thread(new Thread() { @Override public void run() { test.say(); } }, "t1"); Thread t2 = new Thread(new Thread() { @Override public void run() { test.say(); } }, "t2"); Thread t3 = new Thread(new Thread() { @Override public void run() { test.say(); } }, "t3"); t1.start(); try { t1.join(); } catch (InterruptedException e) { e.printStackTrace(); } t2.start(); try { t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } t3.start(); try { t3.join(); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void say() { for (int i = 0; i < 4; i++) { System.out.println(Thread.currentThread().getName() + ":------------------"); if (i == 3) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } }t1:------------------
t1:------------------
t1:------------------
t1:------------------
t2:------------------
t2:------------------
t2:------------------
t2:------------------
t3:------------------
t3:------------------
t3:------------------
t3:------------------
t1.join() 是一个synchronized方法, 里面调用了wait(),这个过程的目的是让持有这个同步锁的线程进入等待,那么谁持有了这个同步锁呢?答案是主线程,因为主线程调用了t1.join()方法,相当于在t1.join()代码这块写了一个同步代码块,谁去执行了这段代码呢,是主线程,所以主线程被wait()了。就是这样子了,要看是谁执行了它,谁持有了它的锁
wait()方法只会让持有锁的线程进入等待,而t1.start()并没有持有锁,所以并不会出现等待的状态