18.4 操作线程的方法

Posted studycode

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了18.4 操作线程的方法相关的知识,希望对你有一定的参考价值。

一、线程的休眠

  一种控制线程行为的方法使调用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 操作线程的方法的主要内容,如果未能解决你的问题,请参考以下文章

线程操作API

活动到片段方法调用带有进度条的线程

线程-使用CountDownEvent类

线程池与并行度

线程同步-使用ReaderWriterLockSlim类

线程学习知识点总结