目錄java
進程:進程指正在運行的程序。確切的來講,當一個程序進入內存運行,即變成一個進程,進程是處於運行過程當中的程序,而且每一個進程都具備必定獨立功能。
線程:線程是進程中的一個執行單元,來完成進程中的某個功能。負責當前進程中程序的執行,一個進程中至少有一個線程。一個進程中是能夠有多個線程的,這個應用程序也能夠稱之爲多線程程序。
簡而言之:一個程序運行後至少有一個進程,一個進程中能夠包含多個線程。多線程
繼承Thread類建立線程併發
public class ThreadTest extends Thread{ private int i; public void run() { for(i=0;i<50;i++) { //當線程繼承Thread類的時候,直接調用this便可獲取當前的進程 //Thread類的getName()方法會返回線程的名字 System.out.println(getName()+" "+i); } } public static void main(String[] args) { for(int i =0;i<50;i++) { System.out.println(Thread.currentThread().getName()+" "+i); if(i==10) { //建立第一個線程 new ThreadTest().start(); //建立第二個線程 new ThreadTest().start(); } } } }
實現Runnable接口建立線程類ide
public class RunnableTest implements Runnable { private int i; @Override public void run() { for(i=0;i<50;i++) { System.out.println(Thread.currentThread().getName()+" "+i); } } public static void main(String[] args) { for(int i =0;i<50;i++) { System.out.println(Thread.currentThread().getName()+" "+i); if(i==10) { RunnableTest rs = new RunnableTest(); new Thread(rs).start(); new Thread(rs).start(); } } } }
實現Runnable的原理和好處函數
使用線程的內匿名內部類方式,能夠方便的實現每一個線程執行不一樣的線程任務操做。this
new Thread() { public void run() { for (int i = 0; i < 10; i++) { System.out.println(getName() + " " + i); } } }.start();
new Thread(new Runnable() { public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + " " + i); } } }).start();
new Thread("yyy") { public void run() { //do something... } }.start();
new Thread() { public void run() { this.setName("abc"); for(int i = 0; i < 100; i++) { System.out.println(this.getName() + "....bb"); } } }.start();
Thread t1 = new Thread() { public void run() { for(int i = 0; i < 50; i++) { System.out.println(getName() + "...aaaaaaaaaaaaaaaaaaaaaa"); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }; Thread t2 = new Thread() { public void run() { for(int i = 0; i < 2; i++) { System.out.println(getName() + "...bb"); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }; t1.setDaemon(true); //將t1設置爲守護線程 t1.start(); t2.start(); //運行結果 Thread-1...bb Thread-0...aaaaaaaaaaaaaaaaaaaaaa Thread-0...aaaaaaaaaaaaaaaaaaaaaa Thread-1...bb Thread-0...aaaaaaaaaaaaaaaaaaaaaa
final Thread t1 = new Thread() { public void run() { for(int i = 0; i < 100; i++) { System.out.println(getName() + "...aaaaaaaaaaaaaaaaaaaaaa"); } } }; Thread t2 = new Thread() { public void run() { for(int i = 0; i < 100; i++) { System.out.println(getName() + "...bb"); try { t1.join(); } catch (InterruptedException e) { e.printStackTrace(); } } } }; t1.start(); t2.start();
public class ThreadT { public void print1() { synchronized (ThreadT.class) { System.out.print("1"); System.out.print("2"); System.out.print("3"); System.out.print("\r\n"); } } public void print2() { synchronized (ThreadT.class) { System.out.print("a"); System.out.print("b"); System.out.print("c"); System.out.print("\r\n"); } } public static void main(String[] args) { ThreadT tT = new ThreadT(); Thread t1 = new Thread() { public void run() { for (int i = 0; i < 100; i++) { tT.print1(); } } }; Thread t2 = new Thread() { public void run() { for (int i = 0; i < 100; i++) { tT.print2(); } } }; t1.start(); t2.start(); } }
public class ThreadT { public synchronized void print1() { System.out.print(Thread.currentThread().getName()+"----"); System.out.print("1"); System.out.print("2"); System.out.print("3"); System.out.print("\r\n"); } public synchronized void print2() { System.out.print(Thread.currentThread().getName()+"----"); System.out.print("a"); System.out.print("b"); System.out.print("c"); System.out.print("\r\n"); } public static void main(String[] args) { ThreadT tT = new ThreadT(); Thread t1 = new Thread() { public void run() { for (int i = 0; i < 1000; i++) { tT.print1(); } } }; Thread t2 = new Thread() { public void run() { for (int i = 0; i < 1000; i++) { tT.print2(); } } }; t1.start(); t2.start(); } } //輸出結果(一部分) Thread-0----123 Thread-0----123 Thread-1----abc Thread-1----abc Thread-1----abc Thread-0----123 Thread-0----123
多個線程併發執行時,在默認狀況下CPU是隨機切換線程的。若是咱們但願他們有規律的執行,就可使用通訊,例如每一個線程執行一次打印。
若是但願線程等待,就調用wait(),若是但願喚醒等待的線程,就調用notify();這兩個方法必須在同步代碼中執行,而且使用同步鎖對象來調用。notifyAll()方法是喚醒全部線程,JDK5以前沒法喚醒指定的一個線程,若是多個線程之間通訊,須要使用notifyAll()通知全部線程,用while來反覆判斷條件。線程
public class ThreadT { private int flag = 1; public synchronized void print1() { try { /* if (flag != 1) { //if 語句是在那裏等待就在那裏起來 this.wait(); }*/ while(flag != 1){ this.wait(); //while循環是循環判斷,每次都會判斷標記 } System.out.print("1"); System.out.print("2"); System.out.print("3"); System.out.print("\r\n"); flag = 2; //this.notify(); this.notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void print2() { try { while(flag != 2){ this.wait(); } System.out.print("a"); System.out.print("b"); System.out.print("c"); System.out.print("\r\n"); flag = 3; this.notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void print3() { try { while(flag != 3){ this.wait(); } System.out.print("+"); System.out.print("-"); System.out.print("*"); System.out.print("\r\n"); flag = 1; this.notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { ThreadT tT = new ThreadT(); Thread t1 = new Thread() { public void run() { for (int i = 0; i < 100; i++) { tT.print1(); } } }; Thread t2 = new Thread() { public void run() { for (int i = 0; i < 100; i++) { tT.print2(); } } }; Thread t3 = new Thread() { public void run() { for (int i = 0; i < 100; i++) { tT.print3(); } } }; t1.start(); t2.start(); t3.start(); } } //輸出結果(一部分) ...... abc +-* 123 abc +-* 123 ......
使用ReentrantLock類的lock()和unlock()方法進行同步。使用Condition的await()和signal()來暫停和喚醒線程設計
public class ThreadT { private int flag = 1; private ReentrantLock rlock = new ReentrantLock(); private Condition c1 = rlock.newCondition(); private Condition c2 = rlock.newCondition(); private Condition c3 = rlock.newCondition(); public void print1() { rlock.lock(); //得到鎖 try { while (flag != 1) { c1.await(); //使當前線程等待,直到發出信號或中斷 } System.out.print("1"); System.out.print("2"); System.out.print("3"); System.out.print("\r\n"); flag = 2; c2.signal(); //喚醒等待線程。 } catch (InterruptedException e) { e.printStackTrace(); } finally { rlock.unlock(); //釋放鎖 } } public void print2() { rlock.lock(); try { while (flag != 2) { c2.await(); } System.out.print("a"); System.out.print("b"); System.out.print("c"); System.out.print("\r\n"); flag = 3; c3.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { rlock.unlock(); } } public void print3() { rlock.lock(); try { while (flag != 3) { c3.await(); } System.out.print("+"); System.out.print("-"); System.out.print("*"); System.out.print("\r\n"); flag = 1; c1.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { rlock.unlock(); } } public static void main(String[] args) { ThreadT tT = new ThreadT(); Thread t1 = new Thread() { public void run() { for (int i = 0; i < 100; i++) { tT.print1(); } } }; Thread t2 = new Thread() { public void run() { for (int i = 0; i < 100; i++) { tT.print2(); } } }; Thread t3 = new Thread() { public void run() { for (int i = 0; i < 100; i++) { tT.print3(); } } }; t1.start(); t2.start(); t3.start(); } }