導師教我們用Java做面向對象式魔方,原來Java還能這麼玩!長見識!

編程語言 Java Java虛擬機 CPU web前端學習 2017-06-26

主線程:執行主方法的線程,就叫做主線程

單線程程序:程序從mani開始從上到下依次運行

程序從main方法開始運行,JVM運行main方法,會找操作系統

開闢一條通向cpu的執行路徑,cpu可以通過這條路徑來執行main方法

這條路徑有一個名字叫主(main)線程

瞭解更多Java知識,獲取原視頻,源碼,學習交流,那就加入小編的學習交流群吧!616 959 444

創建線程方式一繼承Thread類

實現步驟:

1.創建Thread類的子類

2.重寫Thread類中的run方法,設置線程的任務

3.創建Thread類的子類對象

4.調用Thread類中的start方法開啟一個新的線程,執行run方法

使該線程開始執行;Java 虛擬機調用該線程的 run 方法。

結果是兩個線程併發地運行;當前線程(main線程)和另一個線程(執行 run 方法的線程)。

多次啟動一個線程是非法的。特別是當線程已經結束執行後,不能再重新啟動。

打印的結果出現了隨機性:

開啟兩個線程,對於cpu就選擇權利

喜歡誰,就執行誰,所以就出現了隨機性結果

瞭解更多Java知識,獲取原視頻,源碼,學習交流,那就加入小編的學習交流群吧!616 959 444

導師教我們用Java做面向對象式魔方,原來Java還能這麼玩!長見識!

線程的名稱:

主線程:"main"

開啟的其它線程的名稱:"Thread-0","Thread-1"....

獲取線程的名稱

1.Thread類中的方法getName

String getName() 返回該線程的名稱。

2.Thread類中的靜態方法,獲取當前正在執行的線程

static Thread currentThread() 返回對當前正在執行的線程對象的引用。

設置線程的名稱:

1.Thread類中的方法setName(String name)

void setName(String name) 改變線程名稱,使之與參數 name 相同。

2.子類添加帶參構造,調用父類Thread類的帶參構造方法,傳遞線程的名稱,讓父類給線程起名字(讓父親給兒子起名字)

Thread(String name) 分配新的 Thread 對象。

創建線程方式—實現Runnable接口

實現步驟:

1.創建Runnable接口的實現類

2.重寫Runnable接口中的run方法,設置線程任務

3.創建Runnable接口的實現類對象

4.創建Thread類對象,構造方法中傳入Runnable接口的實現類

Thread(Runnable target) 分配新的 Thread 對象。

5.調用Thread類中的方法start,開啟線程執行run方法

實現Runnable的好處

1.避免了類繼承Thread類之後,無法繼承其它的類(單繼承的侷限性)

2.把設置線程任務,和開啟線程進行解耦,增強了擴展性

實現類的作用:就是設置線程任務

Thread類的作用:開啟線程

好處:傳遞不同的實現類,實現類重寫的方法不一樣,可以調用不同的方法

線程的匿名內部類使用

匿名:沒有名字

內部類:寫在其他類內部的類(成員位置:成員內部類,局部位置(方法中):局部內部類)

匿名內部類的格式:

new 父類/接口(){

重寫父類/接口中的方法;

};

多線程的父類:

Thread

Runnable

new Thread(){

//重寫run方法,設置線程任務

@Override

public void run() {

for (int i = 0; i < 20; i++) {

System.out.println(Thread.currentThread().getName()+":"+i);

}

}

}

瞭解更多Java知識,獲取原視頻,源碼,學習交流,那就加入小編的學習交流群吧!616 959 444

以上一堆代碼就是一個創建子類重寫父類方法的過程

相當於: new MyThread().start();

程序出現了線程安全問題:賣了重複的票和不存在的票

解決方案:

第一種方式:可以使用同步代碼塊

synchronized(鎖對象){

產生安全問題的代碼;

訪問了共享數據的代碼;

}

注意:

必須要保證多個線程使用的是同一個鎖對象

//在成員位置上創建一個鎖對象(保證唯一)

Object obj = new Object();

@Override

public void run() {

//讓賣票重複執行

while(true){

* 同步代碼塊

* 程序會頻繁的判斷鎖,獲取鎖,釋放鎖,所以會降低速度

synchronized (obj) {

if(ticket>0){

//為了提高安全問題的概率,讓程序睡眠

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

//賣票ticket--

System.out.println(Thread.currentThread().getName()+"...賣第"+ticket--+"張票");

}

}

}

}

瞭解更多Java知識,獲取原視頻,源碼,學習交流,那就加入小編的學習交流群吧!616 959 444

程序出現了線程安全問題:賣了重複的票和不存在的票

解決方案:

第二種方式:同步方法

使用步驟:

1.把可能出現安全問題的代碼抽取到一個方法中

2.把方法增加一個關鍵字synchronized

修飾符 synchronized 返回值類型 方法名(參數){

可能出現安全問題的代碼;

訪問了共享數據的代碼;

}

同步方法使用的鎖對象是什麼?

使用的就是本類對象new RunnableImpl()-->叫this

靜態的同步方法,使用時什麼鎖對象?

使用的是本類對象的class屬性(反射)

RunnableImpl.class

*@Override

public void run() {

//讓賣票重複執行

while(true){

payTicket2();

}

}

* 靜態的同步方法

public static synchronized void payTicket2(){

synchronized (RunnableImpl.class) {

if(ticket>0){

//為了提高安全問題的概率,讓程序睡眠

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

//賣票ticket--

System.out.println(Thread.currentThread().getName()+"...賣第"+ticket--+"張票");

}

}

}

* 抽取出一個同步方法

* 快捷鍵:alt+shift+m

public ynchronized void payTicket1() {

synchronized (this) {

//System.out.println(this);//cn.itcsat.demo10.RunnableImpl@67064

if(ticket>0){

//為了提高安全問題的概率,讓程序睡眠

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

//賣票ticket--

System.out.println(Thread.currentThread().getName()+"...賣第"+ticket--+"張票");

}

}

}

程序出現了線程安全問題:賣了重複的票和不存在的票

*

* 解決方案:

* 第三種方式:使用Lock接口,JDK1.5之後出現的

*

* java.util.concurrent.locks.Lock接口

* 方法:

* void lock() 獲取鎖。

* void unlock() 釋放鎖。

* 接口的實現類:ReentrantLock

導師教我們用Java做面向對象式魔方,原來Java還能這麼玩!長見識!

*

* 實現步驟:

* 1.在成員位置創建一個Lock接口的實現類對象ReentrantLock

* 2.在可能出現線程安全問題的代碼前,調用lock方法獲取鎖

* 3.在可能出現線程安全問題的代碼後,調用unlock方法釋放鎖

*

*1.在成員位置創建一個Lock接口的實現類對象ReentrantLock

瞭解更多Java知識,獲取原視頻,源碼,學習交流,那就加入小編的學習交流群吧!616 959 444

Lock l = new ReentrantLock();

@Override

public void run() {

//讓賣票重複執行

while(true){

//2.在可能出現線程安全問題的代碼前,調用lock方法獲取鎖

l.lock();

if(ticket>0){

//為了提高安全問題的概率,讓程序睡眠

try {

Thread.sleep(10);

//賣票ticket--

System.out.println(Thread.currentThread().getName()+"...賣第"+ticket--+"張票");

} catch (InterruptedException e) {

e.printStackTrace();

}finally {

//3.在可能出現線程安全問題的代碼後,調用unlock方法釋放鎖

l.unlock();

}

}

}

記住:永遠別放棄你當初踏入社會時的夢想,那是你現在最美好的夢想啊!

相關推薦

推薦中...