多任務,多線程java
在操做系統中運行的程序就是進程,一個進程能夠有多個線程,如視頻中聽聲音,看圖像,看彈幕等。web
程序是指令和數據的有效集合,其自己沒有任何運行的含義,是一個靜態的概念。apache
而進程則是執行程序的一次執行過程,是一個動態的概念,是系統資源分配的單位。安全
一般在一個進程中能夠包含若干個下線程,且至少有一個線程,否則沒有存在的意義,線程是CPU調度和執行的單位。服務器
注意:不少多線程是模擬出來的,真正的多線程是值多個cpu,即多核,如服務器;若是是模擬出來的多線程,則是在一個cpu的狀況 下,在同一個時間點,cpu只能執行一段代碼,由於切換的很快,因此就有同時執行的錯覺。多線程
線程就是獨立的執行路徑。併發
在程序運行時,即便沒有本身建立線程,後臺也會有多個線程,如主線程,gc線程。less
main()稱爲主線程,爲系統的入口,用於執行整個程序。ide
在一個進程中,若是開闢了多個線程,線程的運行由調度器安排調度,調度器是與操做系統緊密相關的,前後順序不能人爲干預。學習
對同一份資源操做時,會存在資源搶奪的問題,須要加入併發控制。
線程會帶來額外的開銷,如cpu調度時間,併發控制開銷。
每一個線程在本身的工做內存交互,內存控制不當會形成數據不一致。
自定義線程類繼承Thread類
重寫run()方法,編寫線程執行體
建立線程對象,調用start()啓動線程
package com.thead.lesson01; //繼承Thread類 重寫run()方法 調用start方法 //線程開啓不必定當即執行, public class TestThread01 extends Thread{ @Override public void run() { //run方法線程體 for (int i = 0; i < 10; i++) { System.out.println("我在看代碼:"+i); } } public static void main(String[] args) { //主方法main線程 //建立線程對象 TestThread01 testThread01 = new TestThread01(); //開啓線程 testThread01.start(); for (int i = 0; i < 10; i++) { System.out.println("我在學習:"+i); } } }
使用多線程下載3張圖片,先下載commons-io jar包 ,建立lib包,jar包放到lib包下,右擊lib包Add as Library。
package com.thread.lesson01; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; //練習thread實現多線程下載圖片 public class TestThread02 extends Thread{ private String url; private String name; public TestThread02(String url,String name){ this.url = url;//圖片地址 this.name = name;//文件名 } //下載圖片線程執行體 @Override public void run() { WebDownLoader webDownLoader = new WebDownLoader(); webDownLoader.downloader(url,name); System.out.println("下載了文件名爲:"+name); } public static void main(String[] args) { TestThread02 t1 = new TestThread02("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png","1.jpg"); TestThread02 t2 = new TestThread02("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png","2.jpg"); TestThread02 t3 = new TestThread02("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png","3.jpg"); t1.start(); t2.start(); t3.start(); } } //下載器 class WebDownLoader{ //下載方法 public void downloader(String url,String name) { try { FileUtils.copyURLToFile(new URL(url),new File(name)); } catch (IOException e) { e.printStackTrace(); } } }
定義MyRunnable類實現Runnable接口
實現run()方法,編寫線程執行體
建立線程對象,調用start()方法啓動線程
不建議使用Thread,避免OOP單繼承侷限性,推薦使用Runnable,方便同一個對象被多個線程使用。
package com.thread.lesson01; //實現runnable接口,重寫run方法,執行線程須要丟入runable接口實現類,調用start方法 public class TestThread03 implements Runnable{ @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("我在讀書!"+i); } } public static void main(String[] args) { //建立runable接口實現類對象 TestThread03 t3 = new TestThread03(); //建立線程對象i //Thread thread = new Thread(t3); //thread.start(); new Thread(t3).start(); for (int i = 0; i < 100; i++) { System.out.println("我在學多線程!"+i); } } }
下載圖片
package com.thread.lesson01; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; import java.net.URL; //練習Runnable實現多線程下載圖片 public class TestThread04 implements Runnable{ private String url; private String name; public TestThread04(String url,String name){ this.url = url;//圖片地址 this.name = name;//文件名 } //下載圖片線程執行體 @Override public void run() { WebDownLoaders webDownLoader = new WebDownLoaders(); webDownLoader.downloader(url,name); System.out.println("下載了文件名爲:"+name); } public static void main(String[] args) { TestThread04 t1 = new TestThread04("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png","1.jpg"); TestThread04 t2 = new TestThread04("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png","2.jpg"); TestThread04 t3 = new TestThread04("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png","3.jpg"); new Thread(t1).start(); new Thread(t2).start(); new Thread(t3).start(); } } //下載器 class WebDownLoaders{ //下載方法 public void downloader(String url,String name) { try { FileUtils.copyURLToFile(new URL(url),new File(name)); } catch (IOException e) { e.printStackTrace(); } } }
模擬搶票
package com.thread.lesson01; //多個線程同時操做同一個對象(買火車票) //發現問題,多個進程操做同一個資源的狀況下,線程不安全,數據紊亂 public class TestThread05 implements Runnable{ //票數 private int tickeNums = 10; @Override public void run() { while (true){ if (tickeNums<=0){ break; } //模擬延時 try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"拿到了第"+tickeNums--+"張票"); } } public static void main(String[] args) { TestThread05 t5 = new TestThread05(); new Thread(t5,"小周").start(); new Thread(t5,"小秦").start(); new Thread(t5,"小王").start(); } }
模擬龜兔賽跑
package com.thread.lesson01; //模擬龜兔賽跑 public class Race implements Runnable{ //勝利者 private static String winner; @Override public void run() { for (int i = 0; i <= 100; i++) { //模擬兔子休息 if (Thread.currentThread().getName().equals("兔子")&&i%20==0){ try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } //判斷比賽是否結束 boolean flag = gameOver(i); //若是比賽結束 中止程序 if (flag){ break; } System.out.println(Thread.currentThread().getName()+"跑了"+i+"步"); } } //判斷是否完成比賽 private boolean gameOver(int steps){ //判斷是否有勝利者 if (winner!=null){//已經存在勝利者了 return true; }{ if (steps>=100){ winner = Thread.currentThread().getName(); System.out.println("winner is"+winner); return false; } } return false; } public static void main(String[] args) { Race race = new Race(); new Thread(race,"兔子").start(); new Thread(race,"烏龜").start(); } }
瞭解便可
package com.thread.lesson01; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.concurrent.*; //實現Callable接口 //有返回值 拋出了異常 public class TestThread06 implements Callable<Boolean> { private String url; private String name; public TestThread06(String url,String name){ this.url = url;//圖片地址 this.name = name;//文件名 } //下載圖片線程執行體 @Override public Boolean call() { WebDownLoader3 webDownLoader = new WebDownLoader3(); webDownLoader.downloader(url,name); System.out.println("下載了文件名爲:"+name); return true; } public static void main(String[] args) throws ExecutionException, InterruptedException { TestThread06 t1 = new TestThread06("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png","1.jpg"); TestThread06 t2 = new TestThread06("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png","2.jpg"); TestThread06 t3 = new TestThread06("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png","3.jpg"); // 建立執行服務 ExecutorService ser = Executors.newFixedThreadPool(3); //提交執行 Future<Boolean> r1 = ser.submit(t1); Future<Boolean> r2 = ser.submit(t2); Future<Boolean> r3 = ser.submit(t3); // 獲取結果 boolean rs1 = r1.get(); boolean rs2 = r2.get(); boolean rs3 = r3.get(); //關閉服務 ser.shutdownNow(); } } //下載器 class WebDownLoader3{ //下載方法 public void downloader(String url,String name) { try { FileUtils.copyURLToFile(new URL(url),new File(name)); } catch (IOException e) { e.printStackTrace(); } } }