• 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时间片来执行。

  • 相关阅读:
    每日练习
    AttributeError: module 'torch.jit' has no attribute 'get_trace_graph
    2020.3-SEAN: Image Synthesis with Semantic Region-Adaptive Normalization
    2019-11-DHAN~Towards Ghost-free Shadow Removal via Dual Hierarchical Aggregation Network and Shadow Matting GAN
    2020.2-DMFN-Image Fine-grained Inpainting
    Face completion with Hybrid Dilated Convolution
    FCSR-GAN: Joint Face Completion and Super-resolution via Multi-task Learning
    Joint Face Completion and Super-resolution using Multi-scale Feature Relation Learning
    浮点数转化为字符串
    Sublime Text2使用技巧
  • 原文地址:https://www.cnblogs.com/studycode/p/9581437.html
Copyright © 2020-2023  润新知