日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

多线程 java 实例_Java多线程实例学习

發(fā)布時(shí)間:2023/12/19 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程 java 实例_Java多线程实例学习 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1. Java多線程的就緒、運(yùn)行和死亡狀態(tài)

就緒狀態(tài)轉(zhuǎn)換為運(yùn)行狀態(tài):當(dāng)此線程得到處理器資源;

運(yùn)行狀態(tài)轉(zhuǎn)換為就緒狀態(tài):當(dāng)此線程主動(dòng)調(diào)用yield()方法或在運(yùn)行過程中失去處理器資源。

運(yùn)行狀態(tài)轉(zhuǎn)換為死亡狀態(tài):當(dāng)此線程線程執(zhí)行體執(zhí)行完畢或發(fā)生了異常。

此處需要特別注意的是:當(dāng)調(diào)用線程的yield()方法時(shí),線程從運(yùn)行狀態(tài)轉(zhuǎn)換為就緒狀態(tài),但接下來CPU調(diào)度就緒狀態(tài)中的哪個(gè)線程具有一定的隨機(jī)性,因此,可能會(huì)出現(xiàn)A線程調(diào)用了

yield()方法后,接下來CPU仍然調(diào)度了A線程的情況。

由于實(shí)際的業(yè)務(wù)需要,常常會(huì)遇到需要在特定時(shí)機(jī)終止某一線程的運(yùn)行,使其進(jìn)入到死亡狀態(tài)。目前最通用的做法是設(shè)置一boolean型的變量,當(dāng)條件滿足時(shí),使線程執(zhí)行體快速執(zhí)行完畢。如:

1. 代碼

package test;

public class TestStopThread {

public static void main(String[] args) {

MyThread myThread = new MyThread("MyThread");

Thread thread = new Thread(myThread);

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

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

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

if(i == 10){

thread.start();

}

if(i == 30){

myThread.stopThread();

}

}

}

}

class MyThread implements Runnable{

boolean stop = false;

private int i = 50;

private String threadName;

public MyThread(String threadName){

this.threadName = threadName;

}

@Override

public void run() {

while (!stop && i>0){

System.out.println(threadName + "-->" + i--);

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

public void stopThread(){

stop = true;

}

}

2. 運(yùn)行結(jié)果:

main-->0

main-->1

main-->2

main-->3

main-->4

main-->5

main-->6

main-->7

main-->8

main-->9

main-->10

main-->11

MyThread-->50

MyThread-->49

main-->12

MyThread-->48

main-->13

MyThread-->47

main-->14

main-->15

MyThread-->46

main-->16

MyThread-->45

MyThread-->44

main-->17

MyThread-->43

main-->18

MyThread-->42

main-->19

MyThread-->41

main-->20

main-->21

MyThread-->40

main-->22

MyThread-->39

MyThread-->38

main-->23

main-->24

MyThread-->37

MyThread-->36

main-->25

main-->26

MyThread-->35

main-->27

MyThread-->34

main-->28

MyThread-->33

MyThread-->32

main-->29

main-->30

MyThread-->31

MyThread-->30

main-->31

main-->32

main-->33

main-->34

main-->35

...

2. Java多線程的阻塞狀態(tài)與線程控制

1. join()

讓一個(gè)線程等待另一個(gè)線程完成才繼續(xù)執(zhí)行。如A線程線程執(zhí)行體中調(diào)用B線程的join()方法,則A線程被阻塞,知道B線程執(zhí)行完為止,A才能得以繼續(xù)執(zhí)行。

(1)代碼實(shí)例:

package test;

public class TestJoin {

public static void main(String[] args) {

MyJoin myJoin = new MyJoin();

Thread thread = new Thread(myJoin, "MyJoin");

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

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

if(i == 10){

thread.start();

try {

Thread.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

if(i == 20){

try {

thread.join();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

}

class MyJoin implements Runnable{

@Override

public void run() {

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

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

}

}

}

(2)運(yùn)行結(jié)果:

main-->0

main-->1

main-->2

main-->3

main-->4

main-->5

main-->6

main-->7

main-->8

main-->9

main-->10

MyJoin-->0

MyJoin-->1

MyJoin-->2

MyJoin-->3

MyJoin-->4

MyJoin-->5

MyJoin-->6

MyJoin-->7

MyJoin-->8

MyJoin-->9

MyJoin-->10

MyJoin-->11

MyJoin-->12

MyJoin-->13

MyJoin-->14

MyJoin-->15

MyJoin-->16

MyJoin-->17

MyJoin-->18

MyJoin-->19

main-->11

main-->12

main-->13

main-->14

main-->15

main-->16

main-->17

main-->18

main-->19

main-->20

main-->21

main-->22

main-->23

main-->24

main-->25

main-->26

main-->27

main-->28

main-->29

可以看到,當(dāng)main線程中join 了MyJoin線程后,會(huì)暫停main線程,直到MyJoin線程執(zhí)行完畢再執(zhí)行main,這就是join方法,說簡(jiǎn)單點(diǎn),就是A線程中調(diào)用B線程join方法,此時(shí),A線程暫停執(zhí)行(阻塞),而B線程執(zhí)行,直到B線程執(zhí)行完畢后A線程繼續(xù)執(zhí)行

2. sleep()

sleep —— 讓當(dāng)前的正在執(zhí)行的線程暫停指定的時(shí)間,并進(jìn)入阻塞狀態(tài)。在其睡眠的時(shí)間段內(nèi),該線程由于不是處于就緒狀態(tài),因此不會(huì)得到執(zhí)行的機(jī)會(huì)。即使此時(shí)系統(tǒng)中沒有任何其他可執(zhí)行的線程,出于sleep()中的線程也不會(huì)執(zhí)行。因此sleep()方法常用來暫停線程執(zhí)行。

前面有講到,當(dāng)調(diào)用了新建的線程的start()方法后,線程進(jìn)入到就緒狀態(tài),可能會(huì)在接下來的某個(gè)時(shí)間獲取CPU時(shí)間片得以執(zhí)行,如果希望這個(gè)新線程盡快執(zhí)行,直接調(diào)用原來線程的sleep(1)即可。

(1)代碼實(shí)例:

package test;

public class TestSleep {

public static void main(String[] args) {

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

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

if(i == 10){

new Thread(new MySleep(), "MySleep").start();

try {

Thread.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

}

class MySleep implements Runnable{

@Override

public void run() {

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

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

}

}

}

(2)運(yùn)行結(jié)果:

main-->0

main-->1

main-->2

main-->3

main-->4

main-->5

main-->6

main-->7

main-->8

main-->9

main-->10

MySleep-->0

MySleep-->1

MySleep-->2

MySleep-->3

MySleep-->4

MySleep-->5

MySleep-->6

MySleep-->7

MySleep-->8

MySleep-->9

MySleep-->10

MySleep-->11

MySleep-->12

MySleep-->13

MySleep-->14

MySleep-->15

MySleep-->16

MySleep-->17

MySleep-->18

MySleep-->19

main-->11

main-->12

main-->13

main-->14

main-->15

main-->16

main-->17

main-->18

main-->19

3. 后臺(tái)線程(Daemon Thread)

后臺(tái)線程主要是為其他線程(相對(duì)可以稱之為前臺(tái)線程)提供服務(wù),或“守護(hù)線程”。如JVM中的垃圾回收線程。

生命周期:后臺(tái)線程的生命周期與前臺(tái)線程生命周期有一定關(guān)聯(lián)。主要體現(xiàn)在:當(dāng)所有的前臺(tái)線程都進(jìn)入死亡狀態(tài)時(shí),后臺(tái)線程會(huì)自動(dòng)死亡(其實(shí)這個(gè)也很好理解,因?yàn)楹笈_(tái)線程存在的目的在于為前臺(tái)線程服務(wù)的,既然所有的前臺(tái)線程都死亡了,那它自己還留著有什么用)。

設(shè)置后臺(tái)線程:調(diào)用Thread對(duì)象的setDaemon(true)方法可以將指定的線程設(shè)置為后臺(tái)線程。

(1)代碼實(shí)例:

package test;

public class TestDeamon {

public static void main(String[] args) {

MyDeamon myDeamon = new MyDeamon();

Thread thread = new Thread(myDeamon, "MyDeamon");

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

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

if(i == 5){

thread.setDaemon(true);

thread.start();

try {

Thread.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

if(i >= 19){

System.out.println("main線程執(zhí)行完畢");

}

}

}

}

class MyDeamon implements Runnable{

@Override

public void run() {

System.out.println("MyDeamon線程開始執(zhí)行");

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

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

try {

Thread.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println("MyDeamon線程執(zhí)行完畢");

}

}

(2)運(yùn)行結(jié)果:

main-->0

main-->1

main-->2

main-->3

main-->4

main-->5

main-->6

MyDeamon線程開始執(zhí)行

main-->7

main-->8

main-->9

main-->10

main-->11

main-->12

main-->13

main-->14

main-->15

main-->16

main-->17

main-->18

main-->19

main線程執(zhí)行完畢

MyDeamon-->0

判斷線程是否是后臺(tái)線程:調(diào)用thread對(duì)象的isDeamon()方法。

注:main線程默認(rèn)是前臺(tái)線程,前臺(tái)線程創(chuàng)建中創(chuàng)建的子線程默認(rèn)是前臺(tái)線程,后臺(tái)線程中創(chuàng)建的線程默認(rèn)是后臺(tái)線程。調(diào)用setDeamon(true)方法將前臺(tái)線程設(shè)置為后臺(tái)線程時(shí),需要在start()方法調(diào)用之前。前天線程都死亡后,JVM通知后臺(tái)線程死亡,但從接收指令到作出響應(yīng),需要一定的時(shí)間,前臺(tái)線程main執(zhí)行完畢后,后臺(tái)線程收到指令結(jié)束線程,由于有一定的響應(yīng)時(shí)間,所以執(zhí)行了一段代碼MyDeamon-->0

4. 改變線程的優(yōu)先級(jí)/setPriority()

每個(gè)線程在執(zhí)行時(shí)都具有一定的優(yōu)先級(jí),優(yōu)先級(jí)高的線程具有較多的執(zhí)行機(jī)會(huì)。每個(gè)線程默認(rèn)的優(yōu)先級(jí)都與創(chuàng)建它的線程的優(yōu)先級(jí)相同。main線程默認(rèn)具有普通優(yōu)先級(jí)。

設(shè)置線程優(yōu)先級(jí):setPriority(int priorityLevel)。參數(shù)priorityLevel范圍在1-10之間,常用的有如下三個(gè)靜態(tài)常量值:

MAX_PRIORITY:10

MIN_PRIORITY:1

NORM_PRIORITY:5

注:具有較高線程優(yōu)先級(jí)的線程對(duì)象僅表示此線程具有較多的執(zhí)行機(jī)會(huì),而非優(yōu)先執(zhí)行。

(1)代碼實(shí)例:

package test;

public class TestPriority {

public static void main(String[] args) {

MyPriority myPriority = new MyPriority();

Thread thread = new Thread(myPriority, "MyPriority");

thread.setPriority(Thread.MAX_PRIORITY);

thread.start();

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

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

}

}

}

class MyPriority implements Runnable{

@Override

public void run() {

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

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

}

}

}

(2)運(yùn)行結(jié)果1:

MyPriority-->0

MyPriority-->1

MyPriority-->2

MyPriority-->3

MyPriority-->4

MyPriority-->5

MyPriority-->6

MyPriority-->7

MyPriority-->8

MyPriority-->9

MyPriority-->10

MyPriority-->11

MyPriority-->12

MyPriority-->13

MyPriority-->14

MyPriority-->15

MyPriority-->16

MyPriority-->17

MyPriority-->18

MyPriority-->19

main-->0

main-->1

main-->2

main-->3

main-->4

main-->5

main-->6

main-->7

main-->8

main-->9

main-->10

main-->11

main-->12

main-->13

main-->14

main-->15

main-->16

main-->17

main-->18

main-->19

運(yùn)行結(jié)果2:

main-->0

MyPriority-->0

MyPriority-->1

MyPriority-->2

MyPriority-->3

MyPriority-->4

MyPriority-->5

MyPriority-->6

MyPriority-->7

MyPriority-->8

MyPriority-->9

MyPriority-->10

MyPriority-->11

MyPriority-->12

MyPriority-->13

MyPriority-->14

MyPriority-->15

MyPriority-->16

MyPriority-->17

MyPriority-->18

MyPriority-->19

main-->1

main-->2

main-->3

main-->4

main-->5

main-->6

main-->7

main-->8

main-->9

main-->10

main-->11

main-->12

main-->13

main-->14

main-->15

main-->16

main-->17

main-->18

main-->19

可以看到,當(dāng)設(shè)置了線程優(yōu)先級(jí)后,優(yōu)先級(jí)高的具有較多的執(zhí)行機(jī)會(huì),但是并不一定優(yōu)先執(zhí)行,運(yùn)行結(jié)果1和2有些許不同,1中MyPriority線程先執(zhí)行,2中main線程先執(zhí)行了一段時(shí)間,后讓給優(yōu)先級(jí)高的MyPriority線程,可見,證實(shí)了"具有較高線程優(yōu)先級(jí)的線程對(duì)象僅表示此線程具有較多的執(zhí)行機(jī)會(huì),而非優(yōu)先執(zhí)行。"

5. 線程讓步:yield()

使當(dāng)前線程從執(zhí)行狀態(tài)(運(yùn)行狀態(tài))變?yōu)榭蓤?zhí)行態(tài)(就緒狀態(tài))。cpu會(huì)從眾多的可執(zhí)行態(tài)里選擇,也就是說,當(dāng)前也就是剛剛的那個(gè)線程還是有可能會(huì)被再次執(zhí)行到的,并不是說一定會(huì)執(zhí)行其他線程而該線程在下一次中不會(huì)執(zhí)行到了。調(diào)用yield方法后,該線程就會(huì)把CPU時(shí)間讓掉,讓其他或者自己的線程執(zhí)行(也就是誰先搶到誰執(zhí)行)

同時(shí),yield()方法還與線程優(yōu)先級(jí)有關(guān),當(dāng)某個(gè)線程調(diào)用yiled()方法從運(yùn)行狀態(tài)轉(zhuǎn)換到就緒狀態(tài)后,CPU從就緒狀態(tài)線程隊(duì)列中只會(huì)選擇與該線程優(yōu)先級(jí)相同或優(yōu)先級(jí)更高的線程去執(zhí)行。

(1)代碼實(shí)例:

package test;

public class TestYield {

public static void main(String[] args) {

MyYield1 myYield1 = new MyYield1();

MyYield2 myYield2 = new MyYield2();

Thread thread1 = new Thread(myYield1, "MyYield1");

Thread thread2 = new Thread(myYield2, "MyYield2");

thread1.setPriority(Thread.MAX_PRIORITY);

thread2.setPriority(Thread.MIN_PRIORITY);

thread1.start();

thread2.start();

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

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

if(i == 10){

Thread.yield();

}

}

}

}

class MyYield1 implements Runnable{

@Override

public void run() {

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

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

}

}

}

class MyYield2 implements Runnable{

@Override

public void run() {

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

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

}

}

}

(2)運(yùn)行結(jié)果:

main-->0

main-->1

main-->2

MyYield1-->0

MyYield1-->1

MyYield1-->2

MyYield1-->3

MyYield1-->4

MyYield1-->5

MyYield1-->6

MyYield1-->7

MyYield1-->8

MyYield1-->9

MyYield1-->10

MyYield1-->11

MyYield1-->12

MyYield1-->13

MyYield1-->14

MyYield1-->15

MyYield1-->16

MyYield1-->17

MyYield1-->18

MyYield1-->19

MyYield1-->20

MyYield1-->21

MyYield1-->22

MyYield1-->23

MyYield1-->24

MyYield1-->25

MyYield1-->26

MyYield1-->27

MyYield1-->28

MyYield1-->29

main-->3

main-->4

main-->5

main-->6

main-->7

main-->8

main-->9

main-->10

main-->11

main-->12

main-->13

main-->14

main-->15

main-->16

main-->17

main-->18

main-->19

main-->20

main-->21

main-->22

main-->23

main-->24

main-->25

main-->26

main-->27

main-->28

main-->29

main-->30

main-->31

main-->32

main-->33

main-->34

main-->35

main-->36

main-->37

main-->38

main-->39

main-->40

main-->41

main-->42

main-->43

main-->44

main-->45

main-->46

main-->47

main-->48

main-->49

MyYield2-->0

MyYield2-->1

MyYield2-->2

MyYield2-->3

MyYield2-->4

MyYield2-->5

MyYield2-->6

MyYield2-->7

MyYield2-->8

MyYield2-->9

MyYield2-->10

MyYield2-->11

MyYield2-->12

MyYield2-->13

MyYield2-->14

MyYield2-->15

MyYield2-->16

MyYield2-->17

MyYield2-->18

MyYield2-->19

MyYield2-->20

MyYield2-->21

MyYield2-->22

MyYield2-->23

MyYield2-->24

MyYield2-->25

MyYield2-->26

MyYield2-->27

MyYield2-->28

MyYield2-->29

總結(jié)

以上是生活随笔為你收集整理的多线程 java 实例_Java多线程实例学习的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。