多線程與高并發(fā)

@[TOC](多線程與高并發(fā))

# 認(rèn)識(shí)并發(fā)與并行

并發(fā)是針對(duì)一個(gè)CPU來講,“同一時(shí)間”執(zhí)行多個(gè)任務(wù)--實(shí)質(zhì)上是劃分時(shí)間片,由于時(shí)間很短給人的感覺是是同時(shí)執(zhí)行的;

并行是針對(duì)多個(gè)CPU來講的,同時(shí)執(zhí)行多個(gè)任務(wù)(一個(gè)CPU執(zhí)行一個(gè)),這是真正意義上的同時(shí)執(zhí)行;

## 入門程序分析(打印---HelloWorld)

```java

class Car{

? ? public void drive(){

? ? ? ? System.out.println("我會(huì)跑");

? ? }

}

public class HuiXinThread {

? ? public static void main(String[] args) {

? ? ? ? Car car=null;

? ? ? ? System.out.println("HelloWorld");//主線程---main()

? ? ? ? car.drive();//異常處理的線程---

? ? ? ? new Car().drive();//運(yùn)行完畢,new Car()匿名對(duì)象會(huì)被回收--垃圾收集器

? ? }

}

```

![在這里插入圖片描述](https://img-blog.csdnimg.cn/f04626e9ef4b4676a6b14462936d67f9.png)所以在我們初學(xué)java時(shí),并非只有一個(gè)線程,其實(shí)是多線程的包括? 主線程、處理異常的線程,以及垃圾收集器線程等等;

### 線程之間是如何搶占CPU資源的?

先來看一個(gè)案例----

![在這里插入圖片描述](https://img-blog.csdnimg.cn/578e547affb14c3bb890d75f8046680d.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81NDA2MTMzMw==,size_16,color_FFFFFF,t_70#pic_center)當(dāng)我們打開一個(gè)程序前,其實(shí)就是存放在電腦中的代碼(靜態(tài)的),打開之后,這個(gè)程序才算開啟,(為他分配空間以及CPU資源),然后在這個(gè)程序中開啟不同的功能--即開啟了多個(gè)線程,然后CPU再次為這些線程服務(wù),如果線程過多,CPU不夠用,那就會(huì)使得一個(gè)CPU要執(zhí)行多個(gè)線程---形成了并發(fā)(采用時(shí)間片機(jī)制),同時(shí)可以為線程設(shè)置優(yōu)先級(jí)來提高相應(yīng)線程被先執(zhí)行的概率(并不是優(yōu)先級(jí)低就一定會(huì)被后執(zhí)行)

### 自定義線程的執(zhí)行

線程的創(chuàng)建方式---

第一種---繼承Thread類

```java

class Car extends? Thread{

? ? @Override

? ? public void run(){

? ? ? ? for (int i=0;i<10;i++){

? ? ? ? System.out.println("我會(huì)跑");}

? ? }

}

public class HuiXinThread {

? ? public static void main(String[] args) {

? ? ? ? //主線程---main()

? ? ? ? for (int i = 0; i <10 ; i++) {

? ? ? ? ? ? System.out.println("HelloWorld"+i);

? ? ? ? }

? ? new Car().run();

? ? }

}

```

這一種并不是多線程,因?yàn)樵摲绞街皇前裷un()當(dāng)成一個(gè)普通方法來執(zhí)行的;,所以運(yùn)行結(jié)果是 先執(zhí)行main--主線程,然后執(zhí)行run(),此時(shí)run也是屬于主線程里面的;

![在這里插入圖片描述](https://img-blog.csdnimg.cn/caeb286452dd4685bcc427aa7f7036db.png)

```java

class Car extends? Thread{

? ? @Override

? ? public void run(){

? ? ? ? for (int i=0;i<10;i++){

? ? ? ? System.out.println("我會(huì)跑");}

? ? }

}

public class HuiXinThread {

? ? public static void main(String[] args) {

? ? ? ? //主線程---main()

? ? ? ? for (int i = 0; i <10 ; i++) {

? ? ? ? ? ? System.out.println("HelloWorld"+i);

? ? ? ? }

? ? new Car().start();

? ? }

}

```

start()是父類的方法,但是與逆行結(jié)果依然跟上面一樣---

![在這里插入圖片描述](https://img-blog.csdnimg.cn/6195a0123dce47bc9caeaa82b0875ff5.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81NDA2MTMzMw==,size_16,color_FFFFFF,t_70)原因是我們在主線程(for循環(huán))執(zhí)行時(shí)并沒有子線程參與進(jìn)來,要想實(shí)現(xiàn)并發(fā)效果需要調(diào)整一下start()方法的位置--

```java

class Car extends? Thread{

? ? @Override

? ? public void run(){

? ? ? ? for (int i=0;i<10;i++){

? ? ? ? System.out.println("我會(huì)跑"+i);}

? ? }

}

public class HuiXinThread {

? ? public static void main(String[] args) {

? ? ? ? //子線程

? ? ? ? new Car().start();

? ? ? ? //主線程---main()

? ? ? ? for (int i = 0; i <10 ; i++) {

? ? ? ? ? ? System.out.println("HelloWorld"+i);

? ? ? ? }

? ? }

}

```

![在這里插入圖片描述](https://img-blog.csdnimg.cn/9145df3672f64465993a8cdd6e5326b5.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81NDA2MTMzMw==,size_16,color_FFFFFF,t_70)

> 運(yùn)行后發(fā)現(xiàn)---有時(shí)候并不一定會(huì)出現(xiàn)并發(fā)---當(dāng)運(yùn)行量少的時(shí)候;

# 為線程設(shè)置名字和獲取線程名字

```java

public class Car extends? Thread{

? ? @Override

? ? public void run(){

? ? ? ? for (int i=0;i<10;i++){

? ? ? ? ? ? System.out.println(this.getName()+i);}

? ? }

}

public class HuiXinThread {

? ? public static void main(String[] args) {

? ? ? ? //子線程

? ? ? ? ? ? Car car= new Car();

? ? ? ? ? ? car.setName("小汽車");

? ? ? ? car.start();

? ? ? ? //主線程---main()

? ? ? ? for (int i = 0; i <10 ; i++) {

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

? ? ? ? }

? ? }

}

```

![在這里插入圖片描述](https://img-blog.csdnimg.cn/8018216a7101479891c210510f6a0ea3.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81NDA2MTMzMw==,size_16,color_FFFFFF,t_70)

還可以通過構(gòu)造器來設(shè)置線程名字---

```java

public class Car extends? Thread{

? ? public Car(String name){

? ? ? ? super(name);

? ? }

? ? @Override

? ? public void run(){

? ? ? ? for (int i=0;i<10;i++){

? ? ? ? ? ? System.out.println(this.getName()+i);}

? ? }

}

public class HuiXinThread {

? ? public static void main(String[] args) {

? ? ? ? //子線程

? ? ? ? ? ? Car car= new Car("小火車");

? ? ? ? ? ? //car.setName("小汽車");

? ? ? ? car.start();

? ? ? ? //主線程---main()

? ? ? ? for (int i = 0; i <10 ; i++) {

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

? ? ? ? }

? ? }

}

```

![在這里插入圖片描述](https://img-blog.csdnimg.cn/55f6ba64fdd7420a9f09c06638b05af2.png)

設(shè)置線程名的父類構(gòu)造方法---

![在這里插入圖片描述](https://img-blog.csdnimg.cn/1d470a6200734ac0a083cb6a36a8df6e.png)

# 線程開啟的方式---

## 繼承Thread類--

演示代碼如上,不在贅述----注意點(diǎn)為? 開啟線程是start()方法,而run()方法還是當(dāng)作一個(gè)普通方法來處理的;

start()源碼---

> 此方法不為主方法線程或“系統(tǒng)”調(diào)用。?

> 虛擬機(jī)創(chuàng)建/設(shè)置的組線程。 添加的新功能?

> 到這個(gè)方法以后可能還需要添加到VM中。

![在這里插入圖片描述](https://img-blog.csdnimg.cn/f66733f94539419ea0f14108c96632e7.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81NDA2MTMzMw==,size_16,color_FFFFFF,t_70)

## 實(shí)現(xiàn)Runable接口

```java

class BuyBook implements Runnable{

? ? @Override

? ? public void run() {

? ? ? ? for (int i = 0; i < 10; i++) {

? ? ? ? ? ? System.out.println("i---"+Thread.currentThread());

? ? ? ? }

? ? }

}

public class Test {

? ? public static void main(String[] args)? {

? ? ? ? BuyBook bb= new BuyBook();

? ? ? ? bb.run();

? ? ? ? for (int i = 0; i <10 ; i++) {

? ? ? ? ? ? System.out.println("i---"+Thread.currentThread());

? ? ? ? }

? ? }

}

```

![在這里插入圖片描述](https://img-blog.csdnimg.cn/722edded37734ceda44008f97eb42cce.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81NDA2MTMzMw==,size_16,color_FFFFFF,t_70)

> Runnable接口中只有一個(gè)run方法,

![在這里插入圖片描述](https://img-blog.csdnimg.cn/582525a34919410288ed0d6c325ad153.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81NDA2MTMzMw==,size_16,color_FFFFFF,t_70)

并沒有發(fā)現(xiàn)start方法,需要怎么做呢?

start()方法在Thread類中,所以要先在創(chuàng)建一個(gè)Thread的對(duì)象

```java

class BuyBook implements Runnable{

? ? @Override

? ? public void run() {

? ? ? ? for (int i = 0; i < 3; i++) {

? ? ? ? ? ? System.out.println("i---"+Thread.currentThread());

? ? ? ? }

? ? }

}

public class Test {

? ? public static void main(String[] args)? {

? ? ? ? Thread.currentThread().setName("主線程");

? ? ? ? BuyBook bb= new BuyBook();

? ? ? ? Thread thread= new Thread(bb);

? ? ? ? thread.setName("子線程");

? ? ? ? thread.start();

? ? ? ? for (int i = 0; i <3 ; i++) {

? ? ? ? ? ? System.out.println("i---"+Thread.currentThread());

? ? ? ? }

? ? }

}

```

> public Thread(Runnable target) {//構(gòu)造器--傳入的是Runnable對(duì)象

? ? ? ? this(null, target, "Thread-" + nextThreadNum(), 0);

? ? }

當(dāng)處理量少的時(shí)候得到的結(jié)果像是順序執(zhí)行的,多運(yùn)行幾次就可以了;

![在這里插入圖片描述](https://img-blog.csdnimg.cn/d81146f50cd84580818ad686c696239d.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81NDA2MTMzMw==,size_16,color_FFFFFF,t_70)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • “高并發(fā)和多線程”總是被一起提起,給人感覺兩者好像相等,實(shí)則高并發(fā) ≠ 多線程 多線程是完成任務(wù)的一種方法,高并發(fā)...
    程序大視界閱讀 507評(píng)論 0 1
  • 場景:進(jìn)屋排隊(duì)打印東西 可重入鎖:排隊(duì)拿到打印權(quán)(鑰匙),開門開鎖,打印完畢,關(guān)門,打算交鑰匙,同學(xué)打電話給來,幫...
    青城樓主閱讀 1,659評(píng)論 0 1
  • 多線程與高并發(fā)編程(一) 什么叫線程,進(jìn)程,協(xié)程?一個(gè)程序啟動(dòng)起來叫做進(jìn)程,可以理解為動(dòng)態(tài)的程序,線程是一個(gè)進(jìn)程的...
    woaihuoguoooo閱讀 190評(píng)論 0 0
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月,有人笑有人哭,有人歡樂有人憂愁,有人驚喜有人失落,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,814評(píng)論 28 54
  • 人工智能是什么?什么是人工智能?人工智能是未來發(fā)展的必然趨勢嗎?以后人工智能技術(shù)真的能達(dá)到電影里機(jī)器人的智能水平嗎...
    ZLLZ閱讀 4,085評(píng)論 0 5

友情鏈接更多精彩內(nèi)容