多線程:
一條執行路徑。多線程完成多個功能併發併發執行的效果。
1.繼承自Thread類,重寫run方法。然後用Thread的start方法啓動線程。
2.實現Runnable接口,實現run方法。然後用Thread的start方法啓動線程。\
介紹一下線程中常用的方法,用一個程序解釋一下:
package day16; public class TestRunable { public static void main(String[] args) { myRunnable m=new myRunnable(); Thread n=new Thread(m,"烏龜"); n.start();//啓動一個新線程。啓動之後jvm會自動執行run方法。 // try { // n.join();//如果在A線程中B線程join進來,則現在執行B的內容,直到B執行完畢才繼續執行A。 // } catch (InterruptedException e) { // e.printStackTrace(); // } // n.run();//線程啓動之後執行的方法。 Thread.currentThread().setName("兔子"); for(int i=0 ;i<100;i++){ try { Thread.sleep(1000);//讓當前線程停止執行(休眠)一段時間。 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+i);//currentThread得到當前運行的線程。 } } } class myRunnable implements Runnable{ public void run(){ for(int i=0 ;i<100;i++){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+i); } } }
此外還有幾個方法:
1.getPriority()、setPriority 得到和設置當前線程的優先級。優先級1-10,如果不指定默認是5. 理論上,誰優先級高,誰被cpu調度的可能性就大。但是優先級低的並不是不執行。資源不足的時候纔有效果。
2.setDaemon:將線程置爲守護線程。只能在線程start之前調用。一般用於爲其他線程提供服務,比如GC。守護線程會隨着其他非守護線程的結束而結束。isDaemon可以用於判斷某個線程是否是守護線程。
3.yield:讓位:讓出執行權,和其他線程爭奪資源,誰拿到cpu時間片誰執行。
線程相關的常用類:
1.Timer:定時器、調度器、計時器。
2.TimerTask:定時任務。
線程間的同步:
方式:
1.同步語句塊:synchronized(obj){}
2.同步方法:在方法前加synchronized修飾符,拿到的仍然是本類對象的鎖。
package day16; import java.util.ArrayList; import java.util.Vector; public class Bank { public static void main(String[] args) { // 創建一個賬戶 Account account = new Account(); // 你和女朋友操作同一個賬戶 Person1 you1 = new Person1(account); Person1 yourGF1 = new Person1(account); Thread thYou1 = new Thread(you1); Thread thYourGF1 = new Thread(yourGF1); // 你和女朋友同時去取錢。 thYou1.start(); thYourGF1.start(); // 存錢線程 Person2 you2 = new Person2(account); Person2 yourGF2 = new Person2(account); Thread thYou2 = new Thread(you2); Thread thYourGF2 = new Thread(yourGF2); thYou2.start(); thYourGF2.start(); try { Thread.sleep(5000);// 確保賬戶操作完畢 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("最終賬戶餘額:"+account.balance); } } class Account{ private ArrayList list; private Vector v ; public int balance = 2000; private Object obj1 = new Object(); // private Object obj2 = new Object(); // 取款 public /*synchronized*/ void withdraw(){// 同一時間只能有一個線程訪問。 synchronized (obj1) { int temp = balance; temp = temp - 800; try { Thread.sleep(1000);// 模擬網絡延遲。 } catch (InterruptedException e) { e.printStackTrace(); } balance = temp; System.out.println(Thread.currentThread().getName()+"取款"); // while(true){} } } // 存款 public /*synchronized*/ void deposit(){// 同一時間只能有一個線程訪問。 synchronized (obj1) { int temp = balance; temp = temp + 800; try { Thread.sleep(1000);// 模擬網絡延遲。 } catch (InterruptedException e) { e.printStackTrace(); } balance = temp; System.out.println(Thread.currentThread().getName()+"存款"); } } } class Person1 implements Runnable{ // 人要自己的賬戶。 private Account account ; public Person1(Account account){ this.account = account; } @Override public void run() { account.withdraw(); } } class Person2 implements Runnable{ // 人要自己的賬戶。 private Account account ; public Person2(Account account){ this.account = account; } @Override public void run() { account.deposit(); } }