java中線程基礎總結
阿新 • • 發佈:2019-05-10
-c system 可控 系統 就會 一秒 pri () 出現
1.線程的創建方式
1.繼承Thread並重寫run方法,run方法是用來定義當前線程
public class ThreadDemo1 { public static void main(String[] args) { Thread t1 = new MyThread1(); Thread t2 = new MyThread2(); /* * 啟動線程要調用start方法而不是run方法。 * 當start方法調用完畢後,run方法很快 * 的被自動執行。View Code*/ t1.start(); t2.start(); } } /* * 繼承線程重寫run方法這樣的做法有兩個不足: * 1.由於java是單繼承,這就導致繼承了Thread就不能繼承 * 其他類。 * 2.由於重寫run方法將線程的任務定義在了線程當中,這就 * 導致線程的重用性變得很差。線程與任務不應有必然的耦合關系。 */ class MyThread1 extends Thread{ public void run(){ for(int i = 0;i<1000;i++){ System.out.println("你是誰啊"); } } } class MyThread2 extends Thread{ public void run(){ for(int i = 0;i<1000;i++){ System.out.println("我是你爸爸"); } } }
2.實現Runable接口單獨定義線程任務
public class ThreadDemo2 { public static void main(String[] args) { Runnable r1View Code= new MyRunnable1(); Runnable r2 = new MyRunnable2(); Thread t1 = new Thread(r1); Thread t2 = new Thread(r2); t1.start(); t2.start(); } } class MyRunnable1 implements Runnable{ public void run(){ for(int i=0;i<1000;i++){ System.out.println("你是誰啊"); } } } class MyRunnable2 implements Runnable{ public void run(){ for(int i= 0;i<1000;i++){ System.out.println("我是你爸爸"); } } }
3.使用匿名內部類來完成兩種方式的線程創建
public class ThreadDemo3 { public static void main(String[] args) { Thread t1 = new Thread(){ public void run(){ for(int i=0;i<1000;i++){ System.out.println("你是誰啊"); } } }; Thread t2 = new Thread(new Runnable(){ public void run(){ for(int i = 0;i<1000;i++){ System.out.println("我是你爸爸"); } } }); t1.start(); t2.start(); } }View Code
2.線程的優先級
/** * 線程優先級 * * 線程對線程調度的工作是不可控的,即: * 線程只能被動被分配CPU時間,而不能主動獲取到。 * * 線程調度會盡可能的將CPU時間分配的幾率做到均勻。但是 * 多個線程開發運行,並不保證一個線程一次這樣交替運行。 * * 可以通過調整線程的優先級改善分配CPU時間片幾率。 * 理論上線程優先級越高的線程,獲取CPU時間片的次數就多。 * * 線程的優先級有10級,分別用整數1-10表示 * 其中1最低,5默認,10最高 * @author tarena * */ public class Thread_setPriorty { public static void main(String[] args) { Thread max = new Thread(){ public void run(){ for(int i=0;i<10000;i++){ System.out.println("max"); } } }; Thread mor = new Thread(){ public void run (){ for(int i=0;i<10000;i++){ System.out.println("mor"); } } }; Thread min = new Thread(){ public void run(){ for(int i = 0;i<10000;i++){ System.out.println("min"); } } }; //改變線程的優先級 max.setPriority(Thread.MAX_PRIORITY); min.setPriority(Thread.MIN_PRIORITY); min.start(); mor.start(); max.start(); } }View Code
3.守護線程的使用
/** * 守護線程,又稱為:後臺線程 * 使用上與前臺線程並無區別,所有線程默認創建出來都是 * 前臺線程,想變為守護線程需要單獨設置。 * * 但是結束時機上有一點不同: * 當進程結束時,所有正在運行的守護線程都會被強制結束。 * 而一個進程中所有前臺線程都結束,進程就會結束。 * @author tarena * */ public class Thread_setDemo { public static void main(String[] args) { Thread rose = new Thread(){ public void run(){ for(int i=0;i<5;i++){ System.out.println("rose:let me go!"); try { Thread.sleep(1000);//使線程進入阻塞狀態 每隔一秒輸出一次for裏面的 } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("rose:啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊"); System.out.println("音效:噗通!"); } }; Thread jack = new Thread(){ public void run(){ while(true){ System.out.println("jack:you jump i jump!"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }; rose.start(); //設置守護線程必須在線程啟動前進行 jack.setDaemon(true); jack.start(); } }View Code
4.線程的相關屬性
public class Thread_Info { public static void main(String[] args) { //取運行main方法的線程 Thread main = Thread.currentThread(); //獲取線程ID long id = main.getId(); System.out.println("id:"+id); //獲取線程名 String name = main.getName(); System.out.println("name:"+name); //是否處於活動狀態 boolean isAlive = main.isAlive(); System.out.println("isAlive:"+isAlive); //是否為守護線程 boolean isDaemon = main.isDaemon(); System.out.println("isDaemon:"+isDaemon); //是否是被中斷 boolean isInterrupted = main.isInterrupted(); System.out.println("isInterrupted:"+isInterrupted); } }View Code
5.線程的阻塞,join方法
/** * 線程是異步運行的 * 異步:合執行各的,互相不妨礙 * 同步:有先後順序的執行。 * * 有些業務需要讓多個線程同時同步進行,這時候可以借助線程的join方法來完成 * * join方法允許一個線程進入阻塞狀態,直到其等待的另一個線程工作結束後再繼續運行。 */ public class Thread_join { public static boolean isFinish = false; public static void main(String[] args) { final Thread download = new Thread(){ public void run(){ System.out.println("dowm:開始下載圖片..."); for(int i = 1;i<=100;i++){ System.out.println("down:"+i+"%"); try { Thread.sleep(10);//阻塞 } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("down:圖片下載完畢!"); isFinish = true; } }; Thread show = new Thread(){ public void run(){ System.out.println("show:開始顯示圖片..."); try { download.join(); } catch (InterruptedException e) { e.printStackTrace(); } /* * 先等待下載線程將圖片下載完畢,再加載 */ if(!isFinish){ throw new RuntimeException("圖片加載失敗!"); } System.out.println("show:顯示圖片完畢!"); } }; download.start(); show.start(); } }View Code
6.線程池的使用
/** * 線程池 * 線程池通常用於: * 1.控制線程數量 * 2.重用線程 * * @author tarena * */ public class ThreadPoolDemo { public static void main(String[] args) { ExecutorService threadPoo1 = Executors.newFixedThreadPool(2);//線程池中包含了2個線程 for(int i = 0;i<5;i++){//5個任務 Runnable runn = new Runnable(){ public void run(){ Thread t = Thread.currentThread(); System.out.println(t.getName()+":正在執行任務"); try { Thread.sleep(5000); } catch (InterruptedException e) { } System.out.println(t.getName()+":任務執行完畢"); } }; threadPoo1.execute(runn); System.out.println("將任務"+i+"指派給線程池"); } //停止線程池 threadPoo1.shutdownNow(); System.out.println("停止了線程池"); } }View Code
線程小知識:
線程存在多線程並發安全問題,即當多個線程同時操作同一資源時,會出現“搶”的情況。由於多線程切換時機不定,可能導致代碼執行順序出現混亂,有悖於程序設計的執行順序而出現邏輯錯誤,嚴重時可能導致系統癱瘓。
java中線程基礎總結