1. 程式人生 > >18.4 操作線程的方法

18.4 操作線程的方法

pac 接口 pin 優先 draw getc javax 無線循環 離開

一、線程的休眠

  一種控制線程行為的方法使調用sleep()方法,sleep()方法需要一個參數用於指定該線程休眠的時間,該時間以毫秒為單位
  sleep()方法的語法如下:
    try{
      Thread.sleep(2000);
    }catch(InterruptedException e){
      e.printStackTrace();
    }
  上述代碼會使線程在2秒之內不會進入就緒狀態。由於sleep()方法的執行有可能拋出InterruptedException異常,所以將sleep()方法的調用放在try-catch塊中。雖然使用sleep()方法的線程在一段時間內會醒來,但是並不能保證它醒來後進入運行狀態,只能保證它進入就緒狀態。

技術分享圖片
 1 package com.lzw;
 2 
 3 import java.awt.*;
 4 import java.util.*;
 5 
 6 import javax.swing.*;
 7 public class SleepMethodTest extends JFrame {
 8     /**
 9      * 
10      */
11     private static final long serialVersionUID = 1L;
12     private Thread t;
13     // 定義顏色數組
14     private static Color[] color = { Color.BLACK, Color.BLUE, Color.CYAN,
15 Color.GREEN, Color.ORANGE, Color.YELLOW, Color.RED, 16 Color.PINK, Color.LIGHT_GRAY }; 17 private static final Random rand = new Random();// 創建隨機對象 18 19 private static Color getC() {// 獲取隨機顏色值的方法 20 return color[rand.nextInt(color.length)]; 21 } 22 23
public SleepMethodTest() { 24 t = new Thread(new Runnable() {// 創建匿名線程對象 25 int x = 30;// 定義初始坐標 26 int y = 50; 27 28 public void run() {// 覆蓋線程接口方法 29 while (true) {// 無限循環 30 try { 31 Thread.sleep(100);// 線程休眠0.1秒 32 } catch (InterruptedException e) { 33 e.printStackTrace(); 34 } 35 // 獲取組件繪圖上下文對象 36 Graphics graphics = getGraphics(); 37 graphics.setColor(getC());// 設置繪圖顏色 38 // 繪制直線並遞增垂直坐標 39 graphics.drawLine(x, y, 100, y++); 40 if (y >= 80) { 41 y = 50; 42 } 43 } 44 } 45 }); 46 t.start();// 啟動線程/ 47 } 48 49 public static void main(String[] args) { 50 init(new SleepMethodTest(), 100, 100); 51 } 52 // 初始化程序界面的方法 53 public static void init(JFrame frame, int width, int height) { 54 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 55 frame.setSize(width, height); 56 frame.setVisible(true); 57 } 58 }
View Code

二、線程的加入

  如果當前某程序為多線程序,加入存在一個線程A,現在需要插入線程B,並要求線程B先執行完畢,然後再繼續執行線程A,此時可以使用Thread類中的join()方法來完成。
  當某個線程使用join()方法加入到另一個線程時,另一個線程會等待該線程執行完畢後再繼續執行。

技術分享圖片
 1 package com.lzw;
 2 
 3 import java.awt.*;
 4 import javax.swing.*;
 5 
 6 public class JoinTest extends JFrame {
 7     /**
 8      * 
 9      */
10     private static final long serialVersionUID = 1L;
11     private Thread threadA; // 定義兩個線程
12     private Thread threadB;
13     final JProgressBar progressBar = new JProgressBar(); // 定義兩個進度條組件
14     final JProgressBar progressBar2 = new JProgressBar();
15     int count = 0;
16     
17     public static void main(String[] args) {
18         init(new JoinTest(), 100, 100);
19     }
20     
21     public JoinTest() {
22         super();
23         // 將進度條設置在窗體最北面
24         getContentPane().add(progressBar, BorderLayout.NORTH);
25         // 將進度條設置在窗體最南面
26         getContentPane().add(progressBar2, BorderLayout.SOUTH);
27         progressBar.setStringPainted(true); // 設置進度條顯示數字字符
28         progressBar2.setStringPainted(true);
29         // 使用匿名內部類形式初始化Thread實例子
30         threadA = new Thread(new Runnable() {
31             int count = 0;
32             
33             public void run() { // 重寫run()方法
34                 while (true) {
35                     progressBar.setValue(++count); // 設置進度條的當前值
36                     try {
37                         Thread.sleep(100); // 使線程A休眠100毫秒
38                         threadB.join(); // 使線程B調用join()方法
39                     } catch (Exception e) {
40                         e.printStackTrace();
41                     }
42                 }
43             }
44         });
45         threadA.start(); // 啟動線程A
46         threadB = new Thread(new Runnable() {
47             int count = 0;
48             
49             public void run() {
50                 while (true) {
51                     progressBar2.setValue(++count); // 設置進度條的當前值
52                     try {
53                         Thread.sleep(100); // 使線程B休眠100毫秒
54                     } catch (Exception e) {
55                         e.printStackTrace();
56                     }
57                     if (count == 100) // 當count變量增長為100時
58                         break; // 跳出循環
59                 }
60             }
61         });
62         threadB.start(); // 啟動線程B
63     }
64     
65     // 設置窗體各種屬性方法
66     public static void init(JFrame frame, int width, int height) {
67         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
68         frame.setSize(width, height);
69         frame.setVisible(true);
70     }
71 }
View Code

技術分享圖片

三、線程的中斷

  以往有的時候回使用stop()方法停止線程,但當前版本的JDK早已廢除了stop()方法,不建議使用stop()方法來停止一個線程的運行。現在提倡在run()方法中使用無線循環的形式,然後使用一個布爾型標記控制循環的停止。
  如果線程因為使用了sleeo()方法或wait()方法進入了就緒狀態,可以使用Thread類中的interrupt()方法時線程離開run()方法,同時結束線程,但程序會拋出InterruptedException異常,用戶可以在處理該異常時完成線程的中斷業務處理,如終止while循環。

技術分享圖片
 1 package com.lzw;
 2 
 3 public class InterruptedTest implements Runnable{
 4     private boolean isContinue = false;    //設置一個編輯變量,默認值為false
 5     
 6     public void run() {
 7         while(true) {
 8             //...
 9             if(isContinue)    //當isContinue變量為true時,停止線程
10                 break;
11         }
12     }
13     
14     public void setContinue() {
15         this.isContinue = true;    //定義設置isContinue變量為true的方法
16     }
17 }
View Code 技術分享圖片
 1 package com.lzw;
 2 
 3 import java.awt.*;
 4 import javax.swing.*;
 5 
 6 public class InterruptedSwing extends JFrame {
 7     /**
 8      * 
 9      */
10     private static final long serialVersionUID = 1L;
11     Thread thread;
12     
13     public static void main(String[] args) {
14         init(new InterruptedSwing(), 100, 100);
15     }
16     
17     public InterruptedSwing() {
18         super();
19         final JProgressBar progressBar = new JProgressBar(); // 創建進度條
20         // 將進度條放置在窗體合適位置
21         getContentPane().add(progressBar, BorderLayout.NORTH);
22         progressBar.setStringPainted(true); // 設置進度條上顯示數字
23         thread = new Thread(new Runnable() {
24             int count = 0;
25             
26             public void run() {
27                 while (true) {
28                     progressBar.setValue(++count); // 設置進度條的當前值
29                     try {
30                         Thread.sleep(1000); // 使線程休眠1000豪秒
31                         // 捕捉InterruptedException異常
32                     } catch (InterruptedException e) {
33                         System.out.println("當前線程序被中斷");
34                         break;
35                     }
36                 }
37             }
38         });
39         thread.start(); // 啟動線程
40         thread.interrupt(); // 中斷線程
41     }
42     
43     public static void init(JFrame frame, int width, int height) {
44         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
45         frame.setSize(width, height);
46         frame.setVisible(true);
47     }
48     
49 }
View Code

技術分享圖片

四、線程的禮讓

  Thread類中提供了一種禮讓方法,使用yield()方法表示,它只是給當前正處於運行狀態的線程一個提醒,告知它可以將資源禮讓給其它線程,但這僅是一種暗示,沒有任何一種機制保證當前線程會將資源禮讓。
  yield()方法使具有同樣優先級的線程有進入可執行狀態的機會,當當前線程放棄執行權時會再度回到就緒狀態。對於支持多任務的操作系統來說,不需要調用yield()方法,因為操作系統會為線程自動分配CPU時間片來執行。

18.4 操作線程的方法