1.join()方法:等子線程執行完成以後再結束主線程.java
例子:dom
public class MyThread extends Thread{ @Override public void run() { try { int sec= (int) (Math.random()*10000); System.out.println(sec); Thread.sleep(sec); } catch (InterruptedException e) { e.printStackTrace(); } } }
public class Test { public static void main(String[] args) throws InterruptedException { MyThread thread=new MyThread(); thread.start(); thread.join(); System.out.println("我想當thread對象執行完畢後我再執行"); System.out.println("但上面代碼中的sleep()中的值寫多少呢?"); System.out.println("答案是不能肯定"); } /* 我想當thread對象執行完畢後我再執行 但上面代碼中的sleep()中的值寫多少呢? 答案是不能肯定 9488 */ }
咱們的目的是先執行子線程再進行打印,解決方法:ide
public class Test { public static void main(String[] args) throws InterruptedException { MyThread thread=new MyThread(); thread.start(); thread.join(); System.out.println("我想當thread對象執行完畢後我再執行"); } /* 5392 我想當thread對象執行完畢後我再執行 */ }
在join的過程當中若是線程被中斷,則當前線程出現異常this
public class ThreadA extends Thread{ @Override public void run() { for (int i = 0; i < Integer.MAX_VALUE; i++) { String newString=new String(""); Math.random(); } } }
public class ThreadB extends Thread{ @Override public void run() { try { ThreadA a=new ThreadA(); a.start(); a.join(); System.out.println("線程B在end處打印了"); } catch (InterruptedException e) { System.out.println("線程B在catch處打印了"); e.printStackTrace(); } } }
public class ThreadC extends Thread{ private ThreadB threadB; public ThreadC(ThreadB threadB){ super(); this.threadB=threadB; } @Override public void run() { threadB.interrupt(); } }
public class Run { public static void main(String[] args) throws InterruptedException { ThreadB b=new ThreadB(); b.start(); Thread.sleep(5000); ThreadC c=new ThreadC(b); c.start(); } /* java.lang.InterruptedException at java.lang.Object.wait(Native Method) at java.lang.Thread.join(Thread.java:1258) at java.lang.Thread.join(Thread.java:1332) at mutithreading.ThreadB.run(ThreadB.java:12) 線程B在catch處打印了 */ }
join(long)的使用: 只等long秒.線程
ps:join()和synchronized()方法的區別:對象
joind在內部使用wait()方法進行等待,而synchronized關鍵字是使用"對象監視器"原理get
join(long)和sleep(long)的區別it
join的功能是使用wait(long)方法來實現的,因此join(long)具備釋放鎖的特色,sleep不會放鎖io
2.ThreadLocal的使用:class
主要解決的就是每一個線程綁定本身的值,能夠將ThreadLocal類比喻成全局存放數據的盒子,盒子中能夠存放存儲每一個線程的私有數據.
證實ThreadLocal的隔離性:
public class ThreadLocalExt extends ThreadLocal{ @Override protected Object initialValue() { return new Date().getTime(); } }
public class Tools { public static ThreadLocalExt t1=new ThreadLocalExt(); }
public class ThreadA extends Thread{ @Override public void run() { try { for (int i = 0; i <100 ; i++) { Tools.t1.set("ThreadA"+(i+1)); System.out.println("ThreadA get Value="+Tools.t1.get()); Thread.sleep(2000); } } catch (InterruptedException e) { e.printStackTrace(); } } }
public class ThreadB extends Thread{ @Override public void run() { try { for (int i = 0; i <100 ; i++) { Tools.t1.set("ThreadB"+(i+1)); System.out.println("ThreadB get Value="+Tools.t1.get()); Thread.sleep(2000); } } catch (InterruptedException e) { e.printStackTrace(); } } }
public class Run { public static void main(String[] args) { try { ThreadA a=new ThreadA(); ThreadB b=new ThreadB(); a.start(); b.start(); for (int i = 0; i <100 ; i++) { Tools.t1.set("Main"+(i+1)); System.out.println("Main get value="+Tools.t1.get()); Thread.sleep(2000); } } catch (InterruptedException e) { e.printStackTrace(); } } /*ThreadA get Value=ThreadA1 Main get value=Main1 ThreadB get Value=ThreadB1 Main get value=Main2 ThreadA get Value=ThreadA2 ThreadB get Value=ThreadB2 */ }
總結:3個線程,每一個線程都set而且get到本身的值.