日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

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

發布時間:2023/12/19 java 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程 java 实例_Java多线程实例学习 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. Java多線程的就緒、運行和死亡狀態

就緒狀態轉換為運行狀態:當此線程得到處理器資源;

運行狀態轉換為就緒狀態:當此線程主動調用yield()方法或在運行過程中失去處理器資源。

運行狀態轉換為死亡狀態:當此線程線程執行體執行完畢或發生了異常。

此處需要特別注意的是:當調用線程的yield()方法時,線程從運行狀態轉換為就緒狀態,但接下來CPU調度就緒狀態中的哪個線程具有一定的隨機性,因此,可能會出現A線程調用了

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

由于實際的業務需要,常常會遇到需要在特定時機終止某一線程的運行,使其進入到死亡狀態。目前最通用的做法是設置一boolean型的變量,當條件滿足時,使線程執行體快速執行完畢。如:

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. 運行結果:

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多線程的阻塞狀態與線程控制

1. join()

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

(1)代碼實例:

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)運行結果:

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

可以看到,當main線程中join 了MyJoin線程后,會暫停main線程,直到MyJoin線程執行完畢再執行main,這就是join方法,說簡單點,就是A線程中調用B線程join方法,此時,A線程暫停執行(阻塞),而B線程執行,直到B線程執行完畢后A線程繼續執行

2. sleep()

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

前面有講到,當調用了新建的線程的start()方法后,線程進入到就緒狀態,可能會在接下來的某個時間獲取CPU時間片得以執行,如果希望這個新線程盡快執行,直接調用原來線程的sleep(1)即可。

(1)代碼實例:

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)運行結果:

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. 后臺線程(Daemon Thread)

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

生命周期:后臺線程的生命周期與前臺線程生命周期有一定關聯。主要體現在:當所有的前臺線程都進入死亡狀態時,后臺線程會自動死亡(其實這個也很好理解,因為后臺線程存在的目的在于為前臺線程服務的,既然所有的前臺線程都死亡了,那它自己還留著有什么用)。

設置后臺線程:調用Thread對象的setDaemon(true)方法可以將指定的線程設置為后臺線程。

(1)代碼實例:

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線程執行完畢");

}

}

}

}

class MyDeamon implements Runnable{

@Override

public void run() {

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

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線程執行完畢");

}

}

(2)運行結果:

main-->0

main-->1

main-->2

main-->3

main-->4

main-->5

main-->6

MyDeamon線程開始執行

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線程執行完畢

MyDeamon-->0

判斷線程是否是后臺線程:調用thread對象的isDeamon()方法。

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

4. 改變線程的優先級/setPriority()

每個線程在執行時都具有一定的優先級,優先級高的線程具有較多的執行機會。每個線程默認的優先級都與創建它的線程的優先級相同。main線程默認具有普通優先級。

設置線程優先級:setPriority(int priorityLevel)。參數priorityLevel范圍在1-10之間,常用的有如下三個靜態常量值:

MAX_PRIORITY:10

MIN_PRIORITY:1

NORM_PRIORITY:5

注:具有較高線程優先級的線程對象僅表示此線程具有較多的執行機會,而非優先執行。

(1)代碼實例:

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)運行結果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

運行結果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

可以看到,當設置了線程優先級后,優先級高的具有較多的執行機會,但是并不一定優先執行,運行結果1和2有些許不同,1中MyPriority線程先執行,2中main線程先執行了一段時間,后讓給優先級高的MyPriority線程,可見,證實了"具有較高線程優先級的線程對象僅表示此線程具有較多的執行機會,而非優先執行。"

5. 線程讓步:yield()

使當前線程從執行狀態(運行狀態)變為可執行態(就緒狀態)。cpu會從眾多的可執行態里選擇,也就是說,當前也就是剛剛的那個線程還是有可能會被再次執行到的,并不是說一定會執行其他線程而該線程在下一次中不會執行到了。調用yield方法后,該線程就會把CPU時間讓掉,讓其他或者自己的線程執行(也就是誰先搶到誰執行)

同時,yield()方法還與線程優先級有關,當某個線程調用yiled()方法從運行狀態轉換到就緒狀態后,CPU從就緒狀態線程隊列中只會選擇與該線程優先級相同或優先級更高的線程去執行。

(1)代碼實例:

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)運行結果:

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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。