內(nèi)容
Ⅰ進程與線程
Ⅱ線程安全
Ⅲ賣票系統(tǒng)demo
具體內(nèi)容
Ⅰ進程與線程
1.(1)進程:正在運行的一個程序
系統(tǒng)會為這個進程分配獨立的內(nèi)存資源
(2)線程:具體執(zhí)行任務的最小單位
一個進程最少擁有一個線程(主線程 運行起來就執(zhí)行的線程)
線程之間是共享內(nèi)存資源的(進程申請的)
線程之間可以通信(數(shù)據(jù)傳遞:多數(shù)為主線程和子線程)
2.進程與線程的關系圖示
3.為什么不使用多進程而是使用多線程豪诲?
線程廉價,線程啟動比較快,退出比較快,對系統(tǒng)資源的沖擊也比較小,而且線程彼此分享了大部分核心對象(File Handle)的擁有權
使用多重進程础浮,不可預期刹悴,且測試困難
4.為什么需要創(chuàng)建子線程
在主線程中存在有比較耗時的操作:下載視頻 上傳文件 數(shù)據(jù)處理
這些操作會阻塞主線程 后面的任務必須等這些任務執(zhí)行完畢之后才能執(zhí)行
為了不阻塞主線程垛孔,需要將耗時的任務放在子線程中去處理
5.創(chuàng)建一個子線程的方法
(1)定義一個類繼承于Thread 實現(xiàn)run方法
join:讓當前這個線程阻塞 等join的線程執(zhí)行完畢再執(zhí)行
setName:設置線程名稱
getName:獲取線程名稱
currentThread:獲取當前運行的線程對象
start:開啟任務
(2)實現(xiàn)Runnable接口 實現(xiàn)run方法
a.創(chuàng)建任務 創(chuàng)建類實現(xiàn)Runnable接口
b.使用Thread 為這個任務分配線程
c.開啟任務 start
(3)創(chuàng)建線程的同時提针,直接開啟線程任務命爬,不需要操作線程對象本身
(4)最簡潔的方式 - 使用Lambda表達式
Ⅱ線程安全
1.什么是線程安全
指的是確保在多條線程訪問的時候,我們的程序還能按照我們預期的行為去執(zhí)行
2.線程的狀態(tài)
NEW:新建 線程剛被創(chuàng)建好 至今尚未啟動的線程處于這種狀態(tài)
RUNNABLE:就緒狀態(tài)辐脖,只要搶到時間片就可以隨時運行這個線程饲宛,正在 Java 虛擬機中執(zhí)行的線程處于這種狀態(tài)
BLOCKED:阻塞狀態(tài) sleep wait
WAITING:等待 wait
TIMED_WAITING:限時等待一個正在限時等待另一個線程執(zhí)行一個動作的線程處于這一狀態(tài)
TERMINATED:終止,已退出的線程處于這種狀態(tài)
3.如何實現(xiàn)線程安全
(1)使用synchronized
synchronized關鍵字嗜价,就是用來控制線程同步的艇抠,保證我們的線程在多線程環(huán)境下,不被多個線程同時執(zhí)行久锥,確保我們數(shù)據(jù)的完整性家淤,使用方法一般是加在方法上
(2)使用Lock
4.同步鎖中await、signal和signalAll的使用
Condition實例被綁定在一個Lock的對象上瑟由,使用Lock對象的方法newCondition()獲取Condition的實例絮重。Condition提供了下面三種方法,來協(xié)調不同線程的同步:
await():導致當前線程等待歹苦,直到其他線程調用該Condition的signal()或signalAll()方法喚醒該線程
signal():喚醒在此Lock對象上等待的單個線程
signalAll():喚醒在此Lock對象上等待的所有線程
Ⅲ賣票系統(tǒng)demo
public static void main(String[] args) {
Ticket ticketCQ = new Ticket("重慶");
Thread t1 = new Thread(ticketCQ);
t1.start();
Ticket ticketSH = new Ticket("上海");
Thread t2 = new Thread(ticketSH);
t2.start();
}
}
//用于賣票的任務
class Ticket implements Runnable {
//定義所有車票的數(shù)量
public static int num = 100;
String name;
public Ticket(String name) {
this.name = name;
}
static final Object obj = new Object();
//創(chuàng)建一個可重入的鎖
static ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
//判斷有沒有票
//加鎖
// synchronized (obj) {
lock.lock();
//需要同步的代碼
if (num > 0) {
System.out.println(name + "出票:" + num);
num--;
// try {
// //當前線程等待
// obj.notify();
// obj.wait();
// } catch (InterruptedException e) {
// e.printStackTrace();
// } finally {
// //通知其他線程執(zhí)行
//
// }
} else {
break;
}
//解鎖
lock.unlock();
}
}