zoukankan      html  css  js  c++  java
  • Java知多少(65)线程的挂起、恢复和终止

    有时,线程的挂起是很有用的。例如,一个独立的线程可以用来显示当日的时间。如果用户不希望用时钟,线程被挂起。在任何情形下,挂起线程是很简单的,一旦挂起,重新启动线程也是一件简单的事。

    挂起,终止和恢复线程机制在Java 2和早期版本中有所不同。尽管你运用Java 2的途径编写代码,你仍需了解这些操作在早期Java环境下是如何完成的。例如,你也许需要更新或维护老的代码。你也需要了解为什么Java 2会有这样的变化。因为这些原因,下面内容描述了执行线程控制的原始方法,接着是Java 2的方法。

    Java 1.1或更早版本的线程的挂起、恢复和终止

    先于Java2的版本,程序用Thread 定义的suspend() 和 resume() 来暂停和再启动线程。它们的形式如下:
        final void suspend( )
        final void resume( )
    下面的程序描述了这些方法:

     1 // Using suspend() and resume().
     2 class NewThread implements Runnable {
     3     String name; // name of thread
     4     Thread t;
     5     NewThread(String threadname) {
     6         name = threadname;
     7         t = new Thread(this, name);
     8         System.out.println("New thread: " + t);
     9         t.start(); // Start the thread
    10     }
    11     // This is the entry point for thread.
    12     public void run() {
    13         try {
    14             for(int i = 15; i > 0; i--) {
    15                 System.out.println(name + ": " + i);
    16                 Thread.sleep(200);
    17             }
    18         } catch (InterruptedException e) {
    19             System.out.println(name + " interrupted.");
    20         }
    21         System.out.println(name + " exiting.");
    22     }
    23 }
    24 class SuspendResume {
    25     public static void main(String args[]) {
    26         NewThread ob1 = new NewThread("One");
    27         NewThread ob2 = new NewThread("Two");
    28         try {
    29             Thread.sleep(1000);
    30             ob1.t.suspend();
    31             System.out.println("Suspending thread One");
    32             Thread.sleep(1000);
    33             ob1.t.resume();
    34             System.out.println("Resuming thread One");
    35             ob2.t.suspend();
    36             System.out.println("Suspending thread Two");
    37             Thread.sleep(1000);
    38             ob2.t.resume();
    39             System.out.println("Resuming thread Two");
    40         } catch (InterruptedException e) {
    41             System.out.println("Main thread Interrupted");
    42         }
    43         // wait for threads to finish
    44         try {
    45             System.out.println("Waiting for threads to finish.");
    46             ob1.t.join();
    47             ob2.t.join();
    48         } catch (InterruptedException e) {
    49             System.out.println("Main thread Interrupted");
    50         }
    51         System.out.println("Main thread exiting.");
    52     }
    53 }

    程序的部分输出如下:

     1 New thread: Thread[One,5,main]
     2 One: 15
     3 New thread: Thread[Two,5,main]
     4 Two: 15
     5 One: 14
     6 Two: 14
     7 One: 13
     8 Two: 13
     9 One: 12
    10 Two: 12
    11 One: 11
    12 Two: 11
    13 Suspending thread One
    14 Two: 10
    15 Two: 9
    16 Two: 8
    17 Two: 7
    18 Two: 6
    19 Resuming thread One
    20 Suspending thread Two
    21 One: 10
    22 One: 9
    23 One: 8
    24 One: 7
    25 One: 6
    26 Resuming thread Two
    27 Waiting for threads to finish.
    28 Two: 5
    29 One: 5
    30 Two: 4
    31 One: 4
    32 Two: 3
    33 One: 3
    34 Two: 2
    35 One: 2
    36 Two: 1
    37 One: 1
    38 Two exiting.
    39 One exiting.
    40 Main thread exiting.

    Thread类同样定义了stop() 来终止线程。它的形式如下:

        void stop( )
    一旦线程被终止,它不能被resume() 恢复继续运行。

    Java 2中挂起、恢复和终止线程

    Thread定义的suspend(),resume()和stop()方法看起来是管理线程的完美的和方便的方法,它们不能用于新Java版本的程序。下面是其中的原因。Thread类的suspend()方法在Java2中不被赞成,因为suspend()有时会造成严重的系统故障。假定对关键的数据结构的一个线程被锁定的情况,如果该线程在那里挂起,这些锁定的线程并没有放弃对资源的控制。其他的等待这些资源的线程可能死锁。

    Resume()方法同样不被赞同。它不引起问题,但不能离开suspend()方法而独立使用。Thread类的stop()方法同样在Java 2中受到反对。这是因为该方法可能导致严重的系统故障。设想一个线程正在写一个精密的重要的数据结构且仅完成一个零头。如果该线程在此刻终止,则数据结构可能会停留在崩溃状态。

    因为在Java 2中不能使用suspend(),resume()和stop() 方法来控制线程,你也许会想那就没有办法来停止,恢复和结束线程。其实不然。相反,线程必须被设计以使run() 方法定期检查以来判定线程是否应该被挂起,恢复或终止它自己的执行。有代表性的,这由建立一个指示线程状态的标志变量来完成。只要该标志设为“running”,run()方法必须继续让线程执行。如果标志为“suspend”,线程必须暂停。若设为“stop”,线程必须终止。

    当然,编写这样的代码有很多方法,但中心主题对所有的程序应该是相同的。

    下面的例题阐述了从Object继承的wait()和notify()方法怎样控制线程的执行。该例与前面讲过的程序很像。然而,不被赞同的方法都没有用到。让我们思考程序的执行。

    NewTread 类包含了用来控制线程执行的布尔型的实例变量suspendFlag。它被构造函数初始化为false。Run()方法包含一个监测suspendFlag 的同步声明的块。如果变量是true,wait()方法被调用以挂起线程。Mysuspend()方法设置suspendFlag为true。Myresume()方法设置suspendFlag为false并且调用notify()方法来唤起线程。最后,main()方法被修改以调用mysuspend()和myresume()方法。

     1 // Suspending and resuming a thread for Java2
     2 class NewThread implements Runnable {
     3     String name; // name of thread
     4     Thread t;
     5     boolean suspendFlag;
     6     NewThread(String threadname) {
     7         name = threadname;
     8         t = new Thread(this, name);
     9         System.out.println("New thread: " + t);
    10         suspendFlag = false;
    11         t.start(); // Start the thread
    12     }
    13     // This is the entry point for thread.
    14     public void run() {
    15         try {
    16             for(int i = 15; i > 0; i--) {
    17                 System.out.println(name + ": " + i);
    18                 Thread.sleep(200);
    19                 synchronized(this) {
    20                     while(suspendFlag) {
    21                         wait();
    22                     }
    23                 }
    24             }
    25         } catch (InterruptedException e) {
    26             System.out.println(name + " interrupted.");
    27         }
    28         System.out.println(name + " exiting.");
    29     }
    30     void mysuspend() {
    31         suspendFlag = true;
    32     }
    33     synchronized void myresume() {
    34         suspendFlag = false;
    35         notify();
    36     }
    37 }
    38 class SuspendResume {
    39     public static void main(String args[]) {
    40        NewThread ob1 = new NewThread("One");
    41        NewThread ob2 = new NewThread("Two");
    42        try {
    43           Thread.sleep(1000);
    44           ob1.mysuspend();
    45           System.out.println("Suspending thread One");
    46           Thread.sleep(1000);
    47           ob1.myresume();
    48           System.out.println("Resuming thread One");
    49           ob2.mysuspend();
    50           System.out.println("Suspending thread Two");
    51           Thread.sleep(1000);
    52           ob2.myresume();
    53           System.out.println("Resuming thread Two");
    54        } catch (InterruptedException e) {
    55           System.out.println("Main thread Interrupted");
    56        }
    57        // wait for threads to finish
    58        try {
    59           System.out.println("Waiting for threads to finish.");
    60           ob1.t.join();
    61           ob2.t.join();
    62        } catch (InterruptedException e) {
    63            System.out.println("Main thread Interrupted");
    64        }
    65        System.out.println("Main thread exiting.");
    66     }
    67 }

    该程序的输出与前面的程序相同。此书的后面部分,你将看到用Java 2机制控制线程的更多例子。尽管这种机制不像老方法那样“干净”,然而,它是确保运行时不发生错误的方法。它是所有新的代码必须采用的方法。

    系列文章:
  • 相关阅读:
    Linq To Object
    笔试算法
    给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线
    vue3.0中setup的参数
    力扣算法题
    给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组
    vif 与 vfor优先级
    给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。 /返回这三个数的和。
    /给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[
    vue3+canvas随机生成4位验证码
  • 原文地址:https://www.cnblogs.com/Coda/p/4509451.html
Copyright © 2011-2022 走看看