摘自http://www.cnblogs.com/lwbqqyumidi/p/3817517.html本文承接上一篇文章《Java總結篇系列:Java多線程(一)》。 四.Java多線程的阻塞狀態(tài)與線程控制 上文已經(jīng)提到Java阻塞的幾種具體類型,。下面分別看下引起Java線程阻塞的主要方法,。 1.join() join —— 讓一個線程等待另一個線程完成才繼續(xù)執(zhí)行。如A線程線程執(zhí)行體中調(diào)用B線程的join()方法,,則A線程被阻塞,知道B線程執(zhí)行完為止,,A才能得以繼續(xù)執(zhí)行。 1 public class ThreadTest {
2
3 public static void main(String[] args) {
4
5 MyRunnable myRunnable = new MyRunnable();
6 Thread thread = new Thread(myRunnable);
7
8 for (int i = 0; i < 100; i++) {
9 System.out.println(Thread.currentThread().getName() + " " + i);
10 if (i == 30) {
11 thread.start();
12 try {
13 thread.join(); // main線程需要等待thread線程執(zhí)行完后才能繼續(xù)執(zhí)行
14 } catch (InterruptedException e) {
15 e.printStackTrace();
16 }
17 }
18 }
19 }
20 }
21
22 class MyRunnable implements Runnable {
23
24 @Override
25 public void run() {
26 for (int i = 0; i < 100; i++) {
27 System.out.println(Thread.currentThread().getName() + " " + i);
28 }
29 }
30 }
2.sleep() sleep —— 讓當前的正在執(zhí)行的線程暫停指定的時間,,并進入阻塞狀態(tài),。在其睡眠的時間段內(nèi),,該線程由于不是處于就緒狀態(tài),,因此不會得到執(zhí)行的機會,。即使此時系統(tǒng)中沒有任何其他可執(zhí)行的線程,出于sleep()中的線程也不會執(zhí)行,。因此sleep()方法常用來暫停線程執(zhí)行。 前面有講到,,當調(diào)用了新建的線程的start()方法后,,線程進入到就緒狀態(tài),可能會在接下來的某個時間獲取CPU時間片得以執(zhí)行,,如果希望這個新線程必然性的立即執(zhí)行,,直接調(diào)用原來線程的sleep(1)即可,。 1 public class ThreadTest {
2
3 public static void main(String[] args) {
4
5 MyRunnable myRunnable = new MyRunnable();
6 Thread thread = new Thread(myRunnable);
7
8 for (int i = 0; i < 100; i++) {
9 System.out.println(Thread.currentThread().getName() + " " + i);
10 if (i == 30) {
11 thread.start();
12 try {
13 Thread.sleep(1); // 使得thread必然能夠馬上得以執(zhí)行
14 } catch (InterruptedException e) {
15 e.printStackTrace();
16 }
17 }
18 }
19 }
20 }
21
22 class MyRunnable implements Runnable {
23
24 @Override
25 public void run() {
26 for (int i = 0; i < 100; i++) {
27 System.out.println(Thread.currentThread().getName() + " " + i);
28 }
29 }
30 } 注:睡一個毫秒級夠了,,因為CPU不會空閑,會切換到新建的線程,。
3.后臺線程(Daemon Thread) 概念/目的:后臺線程主要是為其他線程(相對可以稱之為前臺線程)提供服務,,或“守護線程”。如JVM中的垃圾回收線程,。 生命周期:后臺線程的生命周期與前臺線程生命周期有一定關聯(lián),。主要體現(xiàn)在:當所有的前臺線程都進入死亡狀態(tài)時,后臺線程會自動死亡(其實這個也很好理解,,因為后臺線程存在的目的在于為前臺線程服務的,,既然所有的前臺線程都死亡了,那它自己還留著有什么用...偉大啊 ! !),。 設置后臺線程:調(diào)用Thread對象的setDaemon(true)方法可以將指定的線程設置為后臺線程,。 1 public class ThreadTest {
2
3 public static void main(String[] args) {
4 Thread myThread = new MyThread();
5 for (int i = 0; i < 100; i++) {
6 System.out.println("main thread i = " + i);
7 if (i == 20) {
8 myThread.setDaemon(true);
9 myThread.start();
10 }
11 }
12 }
13
14 }
15
16 class MyThread extends Thread {
17
18 public void run() {
19 for (int i = 0; i < 100; i++) {
20 System.out.println("i = " + i);
21 try {
22 Thread.sleep(1);
23 } catch (InterruptedException e) {
24 // TODO Auto-generated catch block
25 e.printStackTrace();
26 }
27 }
28 }
29 } 判斷線程是否是后臺線程:調(diào)用thread對象的isDeamon()方法,。 注:main線程默認是前臺線程,前臺線程創(chuàng)建中創(chuàng)建的子線程默認是前臺線程,,后臺線程中創(chuàng)建的線程默認是后臺線程,。調(diào)用setDeamon(true)方法將前臺線程設置為后臺線程時,需要在start()方法調(diào)用之前,。前天線程都死亡后,,JVM通知后臺線程死亡,但從接收指令到作出響應,,需要一定的時間,。
4.改變線程的優(yōu)先級/setPriority(): 每個線程在執(zhí)行時都具有一定的優(yōu)先級,優(yōu)先級高的線程具有較多的執(zhí)行機會,。每個線程默認的優(yōu)先級都與創(chuàng)建它的線程的優(yōu)先級相同。main線程默認具有普通優(yōu)先級,。 設置線程優(yōu)先級:setPriority(int priorityLevel),。參數(shù)priorityLevel范圍在1-10之間,,常用的有如下三個靜態(tài)常量值: MAX_PRIORITY:10 MIN_PRIORITY:1 NORM_PRIORITY:5 獲取線程優(yōu)先級:getPriority(),。 注:具有較高線程優(yōu)先級的線程對象僅表示此線程具有較多的執(zhí)行機會,而非優(yōu)先執(zhí)行,。 1 public class ThreadTest {
2
3 public static void main(String[] args) {
4 Thread myThread = new MyThread();
5 for (int i = 0; i < 100; i++) {
6 System.out.println("main thread i = " + i);
7 if (i == 20) {
8 myThread.setPriority(Thread.MAX_PRIORITY);
9 myThread.start();
10 }
11 }
12 }
13
14 }
15
16 class MyThread extends Thread {
17
18 public void run() {
19 for (int i = 0; i < 100; i++) {
20 System.out.println("i = " + i);
21 }
22 }
23 }
5.線程讓步:yield() 上一篇博文中已經(jīng)講到了yield()的基本作用,,同時,,yield()方法還與線程優(yōu)先級有關,當某個線程調(diào)用yiled()方法從運行狀態(tài)轉換到就緒狀態(tài)后,,CPU從就緒狀態(tài)線程隊列中只會選擇與該線程優(yōu)先級相同或優(yōu)先級更高的線程去執(zhí)行。 1 public class ThreadTest {
2
3 public static void main(String[] args) {
4 Thread myThread1 = new MyThread1();
5 Thread myThread2 = new MyThread2();
6 myThread1.setPriority(Thread.MAX_PRIORITY);
7 myThread2.setPriority(Thread.MIN_PRIORITY);
8 for (int i = 0; i < 100; i++) {
9 System.out.println("main thread i = " + i);
10 if (i == 20) {
11 myThread1.start();
12 myThread2.start();
13 Thread.yield();
14 }
15 }
16 }
17
18 }
19
20 class MyThread1 extends Thread {
21
22 public void run() {
23 for (int i = 0; i < 100; i++) {
24 System.out.println("myThread 1 -- i = " + i);
25 }
26 }
27 }
28
29 class MyThread2 extends Thread {
30
31 public void run() {
32 for (int i = 0; i < 100; i++) {
33 System.out.println("myThread 2 -- i = " + i);
34 }
35 }
36 }
|
|