1. 程式人生 > >(執行緒一)執行緒概念及建立執行緒

(執行緒一)執行緒概念及建立執行緒

概念定義:執行緒是程序中的一個任務,也叫順序執行流,同時執行一個程序中的多個任務(也就是執行多個順序執行流)就是多執行緒

    程式:是作業系統中實現功能的程式碼塊,也叫軟體
    程序:正在執行中的程式
    多程序:多個程式同時執行
    併發:cpu在執行程式時,會將時間劃分為一個一個時間片段,這些時間片段在同一時間只能有一個執行緒在執行,多個執行緒之間,時間片段是走走停停斷斷續續的,但是巨集觀上來看這些時間類似是“一起執行”,我們將多個執行緒同時執行稱之為併發執行緒併發出現在多執行緒中

執行緒建立方式:

     1.繼承Thread類,重寫Thread類中的run方法(執行緒任務體),在主方法中呼叫執行緒方法start()方法啟動執行緒

     2.繼承Runnable介面(任務介面),該介面中有一個run方法是任務體,建立執行緒,將任務作為執行緒的引數傳進來,然後呼叫執行緒的start()方法來啟動執行緒

     3.使用FutureTask來建立執行緒,用Callable來建立任務,然後將FutrueTask作為引數放到執行緒裡,啟動執行緒。

執行緒分類:前臺執行緒、後臺執行緒(守護執行緒)

    前臺執行緒:我們所建立的執行緒預設都為前臺執行緒(注:main方法也是前臺執行緒)

    後臺執行緒(守護執行緒):當所有前臺執行緒結束時,守護執行緒自動結束

執行緒安全:

    當多個執行緒同時使用同一資源時,容易出現執行緒安全問題,此時我們需要用執行緒同步來解決執行緒安全問題

    如何進行執行緒同步:①同步方法(在方法上使用synchronized關鍵字進行鎖定)②同步程式碼塊(在程式碼塊加鎖)

    鎖物件:要執行執行緒同步的物件,可以是任意物件,但是要求每個執行緒看到的鎖物件    必須是同一個才可以,否則起不到執行緒同步的作用

執行緒的狀態:

    1)新建狀態 new 建立執行緒的
    2)就緒狀態 .start()
    3)執行狀態 .run()
    4)阻塞狀態
        a.等待阻塞 .wait()
        b.同步阻塞 鎖物件被其他執行緒佔用,當前執行緒等待其他執行緒釋放        鎖物件
        c.其它阻塞 .sleep() .join()
    5)死亡狀態 執行緒體執行完畢,執行緒死亡

方法:

    ①void sleep():Thread類提供的一個靜態方法

    ②void sleep(long ms):表示讓當前執行緒休眠long毫秒,在此過程中,如果該執行緒被打斷,會丟擲InterruptedException,如果休眠過程一直沒有被打斷,時間一到,執行緒的休眠狀態自動解除,等待cpu的到來,一旦獲得cpu,程式碼便繼續執行

    ③void interrupt():手動打斷某個正在休眠的執行緒,一旦呼叫該方法,則正在休眠的執行緒會丟擲InterruptedException

    ④int getPriority():獲取執行緒優先順序,1-10,10最大,1最小,5正常,理論上,優先順序越高,獲取cpu概率越高

    ⑤void setPriority(int a):設定某個執行緒的優先順序,理論上優先順序越高,獲取cpu的概率越大,實際上可能並非如此

    ⑥Thread currentThread():執行緒提供的一個靜態方法,用來獲取當前正在執行的執行緒

    ⑦void join():等待某個執行緒結束,哪個執行緒呼叫該方法,就等待哪個執行緒,該執行緒結束後才會繼續執行本執行緒後續程式碼

    ⑧void join(long mile):mile最多等待時間,不常用

    ⑨void setDaemon(boolean on):將執行緒設定為守護執行緒

    ⑩boolean isAlive():判斷執行緒是否存活

    ⑪String getName():獲取執行緒名稱

    ⑫long getId():獲取執行緒優先順序

    ⑬boolean isDaemon():判斷是否為守護執行緒

舉例

例一:通過Thread類重寫run方法來建立執行緒並啟動

                        public class ThreadDemo {
                            public static void main(String[] args) {
                                Thread t=new Thread() {
                                    public void run() {
                                        for(int i=0;i<500;i++) {
                                            System.out.println(getName()+":"+i);
                                        }
                                    }
                                };
                                Thread t1=new Thread(new Runnable() {
                                    public void run() {
                                        for(int i=0;i<500;i++) {
                                            System.out.println("中國首富");
                                        }
                                    }
                                });
                                t.start();
                                t1.start();
                            }
                        }

                        執行結果:可見中國首富與序號無順序輸出,因結果冗長此處不進行輸出示例

例二:通過繼承Thread類並重寫run方法來建立並啟動執行緒

                        public class ThreadDemo1 {
                            public static void main(String[] args) {
                                MyTask mt=new MyTask();
                                MyTask1 mt1=new MyTask1();
                                mt.start();
                                mt1.start();
                            }
                        }
                        class MyTask extends Thread{
                            public void run() {
                                for(int i=0;i<500;i++) {
                                    System.out.println("中國");
                                }
                            }
                        }
                        class MyTask1 extends Thread{
                            public void run() {
                                for(int i=0;i<500;i++) {
                                    System.out.println("首富");
                                }
                            }
                        }

                        執行結果:可見中國與首富無順序輸出,因結果冗長此處不進行輸出示例

例三:通過繼承Runnable介面重寫run方法之後將物件作為引數傳入到Thread類中來建立並啟動執行緒

                        public class ThreadDemo2 {
                            public static void main(String[] args) {
                                MyRunnable m=new MyRunnable();
                                Thread t=new Thread(m);
                                MyRunnable1 m1=new MyRunnable1();
                                Thread t1=new Thread(m1);
                                t.start();
                                t1.start();
                            }
                        }
                        class MyRunnable implements Runnable{
                            public void run() {
                                for(int i=0;i<500;i++) {
                                    System.out.println("中國");
                                }
                            }
                        }
                        class MyRunnable1 implements Runnable{
                            public void run() {
                                for(int i=0;i<500;i++) {
                                    System.out.println("首富");
                                }
                            }
                        }

                        執行結果:可見中國與首富無順序輸出,因結果冗長此處不進行輸出示例

例四:通過FutureTask類與Callable介面並重寫call方法後將FutureTask類物件作為引數傳入入Thread類物件中來建立並啟動執行緒

                        import java.util.concurrent.Callable;
                        import java.util.concurrent.FutureTask;
                        public class ThreadDemo4 {
                            public static void main(String[] args) {
                                FutureTask<String> f=new FutureTask<String>(new Callable<String>() {
                                    public String call() throws Exception {
                                        for(int i=0;i<500;i++) {
                                            System.out.println("中國");
                                        }
                                        return null;
                                    }
                                });
                                FutureTask<String> f1=new FutureTask<String>(new Callable<String>() {
                                    public String call() {
                                        for(int i=0;i<500;i++) {
                                            System.out.println("首富");
                                        }
                                        return null;
                                    }
                                });
                                Thread t=new Thread(f);
                                Thread t1=new Thread(f1);
                                t.start();
                                t1.start();
                            }
                        }

                        執行結果:可見中國與首富無順序輸出,因結果冗長此處不進行輸出示例

例五:“我心永恆”執行緒測試

                        public class ThreadDemo5 {
                            public static void main(String[] args) {
                                System.out.println("main方法開始");
                                Thread rose=new Thread() {
                                    public void run() {
                                        for(int i=0;i<10;i++) {
                                            System.out.println("let me go");
                                            try {
                                                Thread.sleep(1500);
                                            } catch (InterruptedException e) {
                                                e.printStackTrace();
                                            }
                                        }
                                        System.out.println("jump");
                                    }
                                };
                                Thread jack=new Thread() {
                                    public void run() {
                                        while(true) {
                                            System.out.println("you jump,i jump");
                                            try {
                                                Thread.sleep(1500);
                                            } catch (InterruptedException e) {
                                                e.printStackTrace();
                                            }
                                        }
                                    }
                                };
                                jack.setDaemon(true);
                                rose.start();
                                jack.start();
                                System.out.println("main方法結束");
                                while(rose.isAlive()) {
                                    System.out.println("劇終");
                                    try {
                                        Thread.sleep(1500);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        }

執行結果:main方法開始
                        main方法結束
                        劇終
                        let me go
                        you jump,i jump
                        let me go
                        you jump,i jump
                        劇終
                        let me go
                        you jump,i jump
                        劇終
                        劇終
                        you jump,i jump
                        let me go
                        let me go
                        you jump,i jump
                        劇終
                        劇終
                        you jump,i jump
                        let me go
                        let me go
                        劇終
                        you jump,i jump
                        劇終
                        let me go
                        you jump,i jump
                        let me go
                        劇終
                        you jump,i jump
                        you jump,i jump
                        let me go
                        劇終
                        jump
                        you jump,i jump
                        劇終
                        you jump,i jump