join()
當線程t1調用t2.join()後,t1保持鎖對象,等待t2執行完,t1進入可執行狀態;
package thread;public class JoinRunnable implements Runnable {Thread t1 ,t2;public JoinRunnable() {t1 = new Thread(this);t1.setName("t1");t2 = new Thread(this);t2.setName("t2");}@Overridepublic void run() { //如果加上synchronized鎖標記,那麼即使t1線程調用了t2.join();由於join不釋放鎖,t2還是無法按預期執行 System.out.println(Thread.currentThread().getName()); if(Thread.currentThread()==t1){//////// try { System.out.println("t2.join();");t2.join();/////////////////} catch (InterruptedException e) {e.printStackTrace();} } for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()); }}public static void main(String[] args){JoinRunnable runnable = new JoinRunnable();runnable.t1.start();runnable.t2.start();}}
運行結果:
t1t2t2.join();t2t2t2t2t2t2t2t2t2t2t1t1t1t1t1t1t1t1t1t1
---------------------------------------------------------------------------------------------------------------------------- sleep()
線上程t1中調用sleep(time),t1保持鎖對象,進入阻塞狀態,time完成後,t1進入可執行狀態。給了低優先順序線程執行的機會。
package thread;public class SleepRunnable implements Runnable {@Overridepublic synchronized void run() { for(int i=0; i<3; i++){ System.out.println(Thread.currentThread().getName()+":"+i); try{ Thread.sleep(100);//線程調用了sleep(100),由於sleep不釋放鎖,其它線程依然無法進入run函數 } catch(InterruptedException e){ System.out.println("Interrupted"); } } }public static void main(String[] args){SleepRunnable myrun = new SleepRunnable();Thread t1 = new Thread(myrun);t1.setName("t1");Thread t2 = new Thread(myrun);t2.setName("t2");t1.start();t2.start();}}
運行結果:
t1:0t1:1t1:2t2:0t2:1t2:2
----------------------------------------------------------------------------------------------------------------------------
yield()
當線程調用yield(),線程直接進入可執行狀態,不放鎖
package thread;public class YieldRunnable implements Runnable {@Overridepublic void run() { //這裡如果用synchronized標記,則其它線程無法進入 for(int i=0; i<3; i++){ System.out.println(Thread.currentThread().getName()+":"+i); Thread.yield();<span style="white-space:pre"></span>////////////// } }public static void main(String[] args){YieldRunnable myrun = new YieldRunnable();Thread t1 = new Thread(myrun);t1.setName("t1");Thread t2 = new Thread(myrun);t2.setName("t2");t1.start();t2.start();}}運行結果:
t1:0t2:0t1:1t2:1t1:2t2:2
----------------------------------------------------------------------------------------------------------------------------
wait()
當現在t1在調用wait()後,線程釋放擁有的鎖,進入線程等待池。當其他線程調用notify時,JVM從線程等待池中取走某一線程,放入鎖標誌等待池。
package thread;public class WaitRunnable implements Runnable {Thread t1 ,t2;public WaitRunnable() {t1 = new Thread(this);t1.setName("t1");t2 = new Thread(this);t2.setName("t2");}@Overridepublic synchronized void run() { if(Thread.currentThread()==t1){ System.out.println("----------"+Thread.currentThread().getName()+" wait 10");try {wait(10);<span style="white-space:pre"></span>////////////} catch (InterruptedException e) {e.printStackTrace();} } for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()); } if(Thread.currentThread()==t2){ System.out.println("---------- t2 done"); notifyAll();<span style="white-space:pre"></span>//////////// }else{ System.out.println("---------- t1 done"); }}public static void main(String[] args){WaitRunnable runnable = new WaitRunnable();runnable.t1.start();runnable.t2.start();}}
運行結果:
----------t1 wait 10t2t2t2t2t2t2t2t2t2t2---------- t2 donet1t1t1t1t1t1t1t1t1t1---------- t1 done