核心數:線程數=1:1 ;使用了超線程技術後---> 1:2java
又稱RR調度,會致使上下文切換編程
進程:程序運行資源分配的最小單位,進程內部有多個線程,會共享這個進程的資源安全
線程:CPU調度的最小單位,必須依賴進程而存在。併發
並行:同一時刻,能夠同時處理事情的能力異步
併發:與單位時間相關,在單位時間內能夠處理事情的能力ide
好處:充分利用cpu的資源、加快用戶響應的時間,程序模塊化,異步化模塊化
存在問題:高併發
線程共享資源,存在衝突;spa
容易致使死鎖;操作系統
啓用太多的線程,就有搞垮機器的可能
一、新啓線程的方式
三種實現方式
繼承類Thread
實現接口Runnable
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /** * @Auther: BlackKingW * @Date: 2019/4/14 12:09 * @Description: */ public class NewThread { /*繼承自Thread類*/ private static class UseThread extends Thread{ @Override public void run() { System.out.println("I am extends Thread"); } } /*實現Runnable接口*/ private static class UseRun implements Runnable{ @Override public void run() { System.out.println("I am implements Runnable"); } } /*實現Callable接口,容許有返回值*/ private static class UseCall implements Callable<String>{ @Override public String call() throws Exception { System.out.println("I am implements Callable"); return "CallResult"; } } public static void main(String[] args) throws InterruptedException, ExecutionException { UseThread useThread = new UseThread(); useThread.start(); UseRun useRun = new UseRun(); new Thread(useRun).start(); Thread t = new Thread(useRun); t.interrupt(); UseCall useCall = new UseCall(); FutureTask<String> futureTask = new FutureTask<>(useCall); new Thread(futureTask).start(); System.out.println(futureTask.get()); } }
一、線程天然終止:天然執行完或拋出未處理異常
二、stop(),resume(),suspend()已不建議使用,stop()會致使線程不會正確釋放資源,suspend()容易致使死鎖。
三、使用interrupt()方法
java線程是協做式,而非搶佔式
調用一個線程的interrupt() 方法中斷一個線程,並非強行關閉這個線程,只是跟這個線程打個招呼,將線程的中斷標誌位置爲true,線程是否中斷,由線程自己決定。
isInterrupted() 斷定當前線程是否處於中斷狀態。
static方法interrupted() 斷定當前線程是否處於中斷狀態,同時中斷標誌位改成false。
方法裏若是拋出InterruptedException,線程的中斷標誌位會被複位成false,若是確實是須要中斷線程,要求咱們本身在catch語句塊裏再次調用interrupt()。
代碼以下
import java.util.concurrent.ExecutionException; /** * @Auther: BlackKingW * @Date: 2019/4/14 12:09 * @Description: */ public class DaemonThread { private static class UseThread extends Thread { @Override public void run() { try { while (!isInterrupted()) { System.out.println(Thread.currentThread().getName() + " I am extends Thread."); } System.out.println(Thread.currentThread().getName() + " interrupt flag is " + isInterrupted()); } finally { System.out.println("...........finally"); } } } public static void main(String[] args) throws InterruptedException, ExecutionException { UseThread useThread = new UseThread(); useThread.start(); Thread.sleep(5); useThread.interrupt(); } }
線程只有5種狀態。整個生命週期就是這幾種狀態的切換。
run()和start() :run方法就是普通對象的普通方法,只有調用了start()後,Java纔會將線程對象和操做系統中實際的線程進行映射,再來執行run方法。
yield() :讓出cpu的執行權,將線程從運行轉到可運行狀態,可是下個時間片,該線程依然有可能被再次選中運行。
取值爲1~10,缺省爲5,但線程的優先級不可靠,不建議做爲線程開發時候的手段
和主線程共死,finally不能保證必定執行,可使用
Thread.setDaemon(true);
方法將線程設置爲守護線程。