JAVA基礎學習總結,day17(線程)

進程:其實就是.exe文件
線程:進程的一個執行單元

1.應用程序包含多個進程
2.進程可以包含多個線程
3.一個java程序其實就是一個進程,一個進程就相當於一個單核cup

並行:同時執行
併發:交替執行

多線程並行:多條線程同時執行
多線程併發:多條線程同時請求執行,但是一個cpu一次只能執行一條線程,所以讓其交替執行,但是由於切換速度比較快,所以你看起來像多線程並行

java中研究的就是多線程併發
1.java程序默認會有兩條線程,一條是main線程,一條是垃圾回收線程
2.線程的調度是搶佔式調度,也就是隨機調度

創建線程類

  1. java使用java.lang.Thread類代表線程,所有的線程對象都必須是Thread類或其子類的實例
  2. 一條線程執行一段任務(一段代碼)
  3. 創建線程並啓動線程的方式

創建線程並啓動線程方式一:通過繼承Thread類

  1. 創建一個子類繼承Thread類
  2. 重寫從Thread類繼承過來的run()方法,把子線程需要執行的代碼放入run()方法中
  3. 創建該子類對象
  4. 使用該子類對象調用start()方法啓動線程
public class MyThread extends Thread{
/**      
* 利用繼承中的特點     
* 將線程名稱傳遞  進行設置      
* */     
public MyThread(String name){     
super(name);         
}     
/*      
* 重寫run方法      
* 定義線程要執行的代碼      
* */     
public void run(){            
for (int i = 0; i < 20; i++) {     
//getName()方法 來自父親             
System.out.println(getName()+i);             
}         
}     
}

測試類
public class Demo {    
public static void main(String[] args) {       
System.out.println("這裏是main線程");        
MyThread mt = new MyThread("小強");                  
mt.start();//開啓了一個新的線程          
for (int i = 0; i < 20; i++) {     
System.out.println("旺財:"+i);             
}         
}     
}

創建線程並啓動線程方式二:通過實現Runnable接口

  1. 創建一個實現類實現Runnable接口
  2. 在實現類中實現run()方法,把子線程需要執行的代碼放入run()方法中
  3. 創建一個Thread類的對象,把實現類的對象作爲參數傳入
  4. 調用start()方法啓動線程
public class MyRunnable implements Runnable{
@Override      
public void run() {     
for (int i = 0; i < 20; i++) {         
System.out.println(Thread.currentThread().getName()+" "+i);             
}         
}     
}

public class Demo {    
public static void main(String[] args) {        
//創建自定義類對象  線程任務對象        
MyRunnable mr = new MyRunnable();        
//創建線程對象        
Thread t = new Thread(mr, "小強");        
t.start();        
for (int i = 0; i < 20; i++) {            
System.out.println("旺財 " + i);        
}    
}
}

創建線程並啓動線程方式三:通過匿名內部類創建線程
1.創建一個Thread類的對象,把Runnable接口的匿名內部類以參數的形式傳入,在匿名內部類中指定任務
2.啓動線程

new Thread(new Runnable(){            
public void run(){               
//多線程要執行的代碼            
}          
}).start();  

Threed類
構造方法:
public Thread() :分配一個新的線程對象。
public Thread(String name) :分配一個指定名字的新的線程對象。
public Thread(Runnable target) :分配一個帶有指定目標新的線程對象。
public Thread(Runnable target,String name) :分配一個帶有指定目標新的線程對象並指定名字。

常用方法:
public String getName() :獲取當前線程名稱。
public void start() :導致此線程開始執行; Java虛擬機調用此線程的run方法。
public void run() :此線程要執行的任務在此處定義代碼。
public static void sleep(long millis) :使當前正在執行的線程以指定的毫秒數暫停(暫時停止執行)。
public static Thread currentThread() :返回對當前正在執行的線程對象的引用。

線程安全問題:使用同步機制來保證線程安全
同步代碼塊:其實就是對 一段代碼進行加鎖
概述:synchronized關鍵字可以用於方法中的某個區塊中,表示只對這個區塊的資源實行互斥訪問
格式:
synchronized(同步鎖){
需要加鎖的代碼

同步鎖:
1.可以寫任意對象
2.多個線程對象要使用同一把鎖

同步方法:其實就是對整個方法進行加鎖
概述:使用synchronized修飾的方法,就叫做同步方法,保證A線程執行該方法的時候,其他線程只能在方法外等着。
格式:
修飾符 synchronized 返回值類型 方法名(參數列表){
可以會產生線程安全問題的代碼

同步鎖是誰?
對於非靜態static方法,同步鎖就是this
對於靜態static方法,我們使用當前方法所在類的字節碼對象(類名.class)

A線程使用的同步代碼塊,B線程使用的同步方法,要想讓這2個線程同時鎖住,那麼A和B線程中的同步要一致

Lock鎖:ReentrantLock 實現類
Lock鎖也稱同步鎖,加鎖與釋放鎖方法化了,如下:
public void lock(): 加同步鎖
public void unlock(); 釋放同步鎖

condition:
await():等待
signal():喚醒
signalAll():喚醒所有

多條線程想要實現同步,那麼鎖必須一致。
線程的六種狀態:新建、可運行、鎖阻塞、無限等待、計時等待、死亡

實現無限等待:
1.使用鎖對象調用wait()方法使得線程進入無限等待
2.無限等待線程想要被喚醒,那麼必須是其他線程使用鎖對象調用notif’y()或者notifyall()方法
3.調用wait()方法和調用notify()或者notifyall()方法的鎖對象必須是一致
4.線程進入無限等待之後,不會搶佔cpu資源,也不會爭奪鎖對象
5.無限等待線程被喚醒了,並且獲取到了鎖對象,那麼線程就會繼續從進入無限等待的位置開始繼續往下執行

線程池
概念:是一個可以放多個線程的容器,其中的線程可以反覆使用
使用線程池中線程對象的步驟:

  1. 創建線程池對象。
  2. 創建Runnable接口子類對象。(task)
  3. 提交Runnable接口子類對象。(take task)
  4. 關閉線程池(一般不做)。

使用:
方法:
public static ExecutorService newFixedThreadPool(int nThreads) :返回線程池對象。(創建的是有界線 程池,也就是池中的線程個數可以指定最大數量)

  // 創建線程池對象        
  ExecutorService service = Executors.newFixedThreadPool(2);//包含2個線程對象

public Future<?> submit(Runnable task) :獲取線程池中的某一個線程對象,並執行

// 從線程池中獲取線程對象,然後調用MyRunnable中的run()        
service.submit(r);
發佈了28 篇原創文章 · 獲贊 13 · 訪問量 1788
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章