1. 程式人生 > >java中線程基礎總結

java中線程基礎總結

-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方法很快
         * 的被自動執行。
         
*/ 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("我是你爸爸"); } } }
View Code

  2.實現Runable接口單獨定義線程任務

技術分享圖片
public class ThreadDemo2 {
    public static void main(String[] args) {
        Runnable r1 
= 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("我是你爸爸"); } } }
View Code

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中線程基礎總結