二 java------線程---線程的控制

線程一些小知識的整理。

一:設置線程的優先級
需求: 定義兩個線程,對線程的優先級別進行設置,並運行!
技能: 引入線程的控制方法--- setPrirority(int i)  getPrirority();
  1.設計線程的優先級別的方法
     1.1 public final void setPriority(int newPriority)
         注意: 被final修飾的方法,只能被繼承不能被重寫!(也可以重載)
              參數---int newPriority    1   5    10
              在Thread當中,存在以下幾個常量:
              線程可以具有的最高優先級。
                 public static final int MAX_PRIORITY   10
              分配給線程的默認優先級。
                 public static final int NORM_PRIORITY  5
              線程可以具有的最低優先級。 
                 public static final int MIN_PRIORITY   1  
         問題: 能否直接寫整數常量?  可以的
         問題: 寫入負整數以及0會出現什麼情況? 輸入的是7或8這些會出現什麼情況?
              推薦怎麼傳入實參?
              1.輸入負數,雖然符合int 的取值範圍,但是在後臺運行時,出現非法參數異常---IllegalArgumentException
              2.發現:優先級別的範圍: 1--10之內的,包括1也包括10
              3.以後在輸入實參時,建議使用Thread類噹噹中的常量
                 Thread.MAX_PRIRORITY  Thread.MIN_PRIRORITY   Thread.NORE_PRIRORITY         
     1.2 public final int getPriority()
         發現:返回值類型是int類型  傳入的是什麼優先級,返回的就是多少。
   2.由於線程具有併發性以及隨機性,即使設置的某個線程的優先級別最高,也不一定先執行!
      原因:   ① 隨機性
            ② 每一個線程都會循環得到自己的時間片,都會搶CPU資源,誰搶到了誰先運行!   
      既然不能保證線程優先執行,爲什麼還要進行設置?
      原因:雖然不能保證優先界別最高的線程先執行,但是他優先執行的概率是很大的!
   3.main方法也是屬於線程,它的優先級別是默認的,也就是5
代碼區:
public class TestPriroprity {
 public static void main(String[] args) {
  
  //1.創建Runnable接口對象
     Runnable r1 = new Tiger();
     Runnable r2 = new Cat();
  //2.藉助Thread類,創建線程對象
    Thread t1 = new Thread(r1);
    Thread t2 = new Thread(r2);
    //線程的優先級
//    t1.setPriority(Thread.MAX_PRIORITY);
//    t2.setPriority(Thread.MIN_PRIORITY);
    t1.setPriority(7);
    t2.setPriority(8);
    System.out.println(t1.getPriority());
    System.out.println(t2.getPriority());
    //獲取main方法也就是主線程的名稱和優先級別
    System.out.println(Thread.currentThread().getName());
    int pri=Thread.currentThread().getPriority();
    System.out.println("pri="+pri);
  //3.啓動線程
    t1.start();
    t2.start();
 }
}
class Tiger  implements Runnable{
 @Override
 public void run() {
  System.out.println("Tiger線程優先級別是最高級---MAX_PRIRORITY");
 }
}
class Cat implements Runnable{
 @Override
 public void run() {
  System.out.println("Tiger線程優先級別是最低級---MIN_PRIRORITY");
 }
}
二:線程的強制加入
需求: 在你做一件好事的時候,即將完成,突然---半路殺出個程咬金
技能: 線程控制方法----強制加入
  1.強制加入的方法---join();
     public final void join() throws InterruptedException
     發現: 使用final修飾以及拋出了異常(中斷異常)
  2.時時刻刻要記住----main方法也是一個線程
  3.思路步驟:
     3.1 先創建一個線程類(創建線程對象),最好實現Runnable接口
     3.2 重寫run()方法,在run()方法內部,定義一個for循環(有限循環)
     3.3 在main方法當中,定義一個for循環---循環次數20次,當循環到10次的時候,另外一個線程強制加入!
       發現:只有強制加入的線程執行完畢之後,其他的線程才能繼續運行,反之,其他線程不能執行!
代碼區:
public class TestJoinThread {
 //主方法也是一個線程
 public static void main(String[] args) {
  //創建ChengYaoJin線程對象
  Runnable r = new ChengYaoJin();
  Thread t = new Thread(r);
  for(int i=1;i<=20;i++){
   System.out.println("牛榮君超級大美女-----自戀"+i);
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
   }
   //當循環到第10次的時候,闞天陽來了....
   if(i==10){
    //啓動線程
    t.start();
    //強制加入,由於此方法拋出異常,所以在調用時必須對異常進行處理----try catch捕捉異常
    try {
     t.join();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   } 
  }
 }
}
class ChengYaoJin  implements Runnable{

 //重寫接口當中的run()方法
 public void run() {
    //因爲run方法是線程的主體,所以要把核心代碼放入到此方法中
  for(int i=1;i<=10;i++){
   System.out.println("誰拿走了我的八塊腹肌----闞天陽"+i);
   try {
    Thread.sleep(500);
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  
 }
 
}
三:線程休眠:
需求1: 運動會---裁判 預備    1  2  3  開始
技能1: 引入線程的控制方法---線程休眠
  需求2: 定義一個時間,時間的格式: HH:mm:ss,每隔一秒進行打印一次!
  技能2: 引入線程的控制方法---線程休眠
  1.線程休眠的方法
     public static void sleep(long millis)throws InterruptedException
     發現: 此方法使用static修飾,所以可以使用類名稱直接調用。此方法拋出異常,所以在調用時必須處理異常---捕捉異常。
  2.此方法的作用
     2.1 線程進行堵塞狀態,休眠時間結束,會在次進入就緒狀態,參與分配CPU資源,運行線程!
     2.2 可以被變相的看成是一個轉換器---例如: 兩個線程交叉運行   線程A運行一次,線程B運行一次,以此類推
         體現: 在定義兩個線程時,在run方法當中,插入線程休眠的方法,具體看實例!
              如果想具體的保證兩個線程的交叉允許,可以使用同步鎖完成!
  3.方法的參數
      long millis --- 毫秒數    單位的換算   1000毫米=1秒
代碼區:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestSleepThread {
 public static void main(String[] args) {
  //1.時間格式化類---DateFormat   SimpleDateFormat()
     DateFormat  df = new SimpleDateFormat("HH:mm:ss");
  //2.定義while循環,目的: 打印時間
     while(true){
      //打印時間,必須有一個Date類對象
        Date d = new Date();
      //DateFormat類存在一個format(Date d) 返回值是String類型
        String now=df.format(d);
        System.out.println(now);
        //每隔一秒進行打印輸出時間
        try {
     Thread.sleep(1000);
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
     }
  
 }
 public static void show(){
  //1.裁判應該先喊: 各就各位    預備
    System.out.println("各就各位    預備..............");
    //2.等待三秒,三秒已過,立即開始執行....
    for (int i = 1; i < 4; i++) {
     System.out.println(i);
     //每一次輸出i的值,需要間隔一秒
     try {
      Thread.sleep(1000);
     } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
     }
    }
    //3.開始
    System.out.println("開始....................");
 }
}
四:線程的禮讓
需求: 古裝劇------西門大官人    林娘子    潘娘子, 定義兩個線程,每一個線程要交叉運行,一個線程喊: 官人  一個線程喊: 娘子   
技能: 線程禮讓的方法----yield();
  1.線程禮讓----yield方法
     暫停當前正在執行的線程對象,並執行其他線程。 
     public static void yield()
     發現: 此方法沒有拋出異常,同時使用static修飾,所以類名稱可以直接調用!
     特點: 暫停正在執行的線程,讓其他線程先執行,而且此方法不是阻塞線程,而是將線程轉入---就緒狀態,不是阻塞狀態
     continue --- 結束本次循環,執行下一次循環
     yield()  --- 讓出當前的CPU資源,讓其他的線程優先執行!
  2.線程要交叉運行--- 解決方案
      2.1 使用的是線程的休眠---發現: 並不一定按照交叉運行,可能是某一個線程執行完畢,另外一個線程才執行。
      2.2 使用線程的禮讓,但是呢,它也不能保證線程的交叉運行,只是一定程度上,可以實現,如果想線程之間真正的交叉允許,需要使用線程同步。
  3.步驟:
      3.1 創建線程---一個線程充當: 男友   -- 官人
                   一個線程充當: 女友   -- 娘子  
          實現的方式: 先通過繼承的方式,在使用實現Runnable接口的方式
      3.2 要重寫run()方法---不管是繼承Thread類也好,還是實現Runnable接口也好,都要重寫run()方法
          原因: 因爲run()方法,是線程的主體,核心代碼放入到此方法中。
      3.3 在重寫的過程當中,可以使用線程休眠也可以使用線程禮讓
      3.4 在main方法當中,創建線程,並啓動線程!
public class TestYieldThread {
 public static void main(String[] args) {
  //1.創建線程對象
      Thread t1 = new GuanRen();
      Thread t2 = new NiangZi();
  //2.爲線程命名
      t1.setName("\t潘娘子");
      t2.setName("西門大官人");
  //3.啓動線程
      t1.start();
      t2.start();
      
 }

}
//創建線程類,通過繼承Thread類實現
class GuanRen  extends Thread{
 //重寫run()方法
 public void run(){
  //for循環語句     目的: 爲了實現交叉運行,肯定有一個定喊話次數 
  for(int i=1;i<=10;i++){
   System.out.println(this.getName()+"喊:官人.....");
   //切換 -- sleep();
//   try {
//    Thread.sleep(1000);
//   } catch (InterruptedException e) {
//    // TODO Auto-generated catch block
//    e.printStackTrace();
//   }
   //線程的禮讓
   Thread.yield();
  }
 }
 
}
class NiangZi extends Thread{
 //重寫run()方法
  public void run(){
   //for循環語句     目的: 爲了實現交叉運行,肯定有一個定喊話次數 
   for(int i=1;i<=10;i++){
    System.out.println(this.getName()+"喊:娘子.....");
    //切換 -- sleep();
//    try {
//     Thread.sleep(1000);
//    } catch (InterruptedException e) {
//     // TODO Auto-generated catch block
//     e.printStackTrace();
//    }
    //線程的禮讓
    Thread.yield();
   }
  }
}
五:設置線程爲後臺線程
需求: 在main方法當中,創建線程,並設置線程爲後臺線程,main方法運行結束之後,後臺線程也隨之結束!
技能: 線程的控制方法-----後臺線程。
  1.設置線程爲後臺線程
      public final void setDaemon(boolean on)
      將該線程標記爲守護線程或用戶線程
      發現:1.此方法使用final修飾  2. 沒有拋出異常  3. 參數類型是布爾值,如果是true則設置爲後臺線程,反之,是前臺線程。
  2.後臺線程---前臺線程
     後臺線程又被稱爲守護線程,前臺線程又被稱爲用戶線程!
     注意: 咱們一般創建的線程都是用戶線程,特別說明: main方法時一個用戶線程
          後臺線程----最典型的例子就是GC---垃圾回收器
  3.設置線程爲後臺線程,必須是在線程的啓動之前,也就是start()方法之前進行設置!
代碼區:
public class TestSetDeamonThread {
    //主方法不僅是一個線程,還是一個用戶線程(前臺線程)
 public static void main(String[] args) {
  //1.創建線程對象
     Runnable r = new QianJinHui(); //目的: 爲Thread類創建對象,做準備
     Thread t = new Thread(r); //根據構造方法,傳入Runnable接口對象
  //2.設置後臺線程
     t.setDaemon(true);
  //3.啓動線程
    t.start();
  //4.也寫一個for循環,for循環執行結束,後臺線程也隨之結束,即使後臺線程中的run方法嵌套了一個死循環,也要結束
    for(int i=1;i<=5;i++){
     System.out.println("週日計劃----休眠"+i);
    }
 }
}
//創建一個線程類
class QianJinHui implements Runnable{

 //重寫run()方法
 public void run() {
  //爲了體現出: 前臺線程結束之後,後臺線程也隨之結束,寫一個死循環
  while(true){
   System.out.println("上課玩手機,該罰-----十個俯臥撐!");
  }
 }
}

原博地址(也是我,O(∩_∩)O哈哈~):http://m15231417197.lofter.com/

練習代碼地址(嘿嘿嘿):https://download.csdn.net/download/m15231417197/10716486

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章