java并发官方文件2

来源:互联网 发布:python while sleep 编辑:程序博客网 时间:2024/05/29 15:09
Java代码 复制代码
  1. public class SleepMessages  
  2.     public static void main(String args[])  
  3.         throws InterruptedException  
  4.         String importantInfo[]  
  5.             "Mares eat oats" 
  6.             "Does eat oats" 
  7.             "Little lambs eat ivy" 
  8.             "A kid will eat ivy too"  
  9.         };  
  10.   
  11.         for (int 0 
  12.              importantInfo.length;  
  13.              i++)  
  14.             //Pause for seconds  
  15.             Thread.sleep(4000);  
  16.             //Print message  
  17.             System.out.println(importantInfo[i]);  
  18.          
  19.      
  20.  
public class SleepMessages {    public static void main(String args[])        throws InterruptedException {        String importantInfo[] = {            "Mares eat oats",            "Does eat oats",            "Little lambs eat ivy",            "A kid will eat ivy too"        };        for (int i = 0;             i < importantInfo.length;             i++) {            //Pause for 4 seconds            Thread.sleep(4000);            //Print a message            System.out.println(importantInfo[i]);        }    }}



main()方法声明了它有可能抛出InterruptedException。当其他线程中断当前线程时,sleep()方法就会抛出该异常。由于这个应用程序并没有定义其他的线程,所以并不用关心如何处理该异常。

中断(Interrupts)

中断是给线程的一个指示,告诉它应该停止正在做的事并去做其他事情。一个线程究竟要怎么响应中断请求取决于程序员,不过让其终止是很普遍的做法。这是本文重点强调的用法。

一个线程通过调用对被中断线程的Thread对象的interrupt()方法,发送中断信号。为了让中断机制正常工作,被中断的线程必须支持它自己的中断(即要自己处理中断)

中断支持

线程如何支持自身的中断?这取决于它当前正在做什么。如果线程正在频繁调用会抛InterruptedException异常的方法,在捕获异常之后,它只是从run()方法中返回。例如,假设在SleepMessages的例子中,关键的消息循环在线程的Runnable对象的run方法中,代码可能会被修改成下面这样以支持中断:

Java代码 复制代码
  1. for (int 0importantInfo.length; i++)  
  2.     // Pause for seconds  
  3.     try  
  4.        Thread.sleep(4000);  
  5.     catch (InterruptedException e)  
  6.        // We've been interrupted: no more messages.  
  7.       return 
  8.   
  9.  // Print message  
  10.  System.out.println(importantInfo[i]);  
  11.  
for (int i = 0; i < importantInfo.length; i++) {    // Pause for 4 seconds    try {       Thread.sleep(4000);    } catch (InterruptedException e) {       // We've been interrupted: no more messages.      return; } // Print a message System.out.println(importantInfo[i]);}



许多会抛InterruptedException异常的方法(如sleep()),被设计成接收到中断后取消它们当前的操作,并在立即返回。

如果一个线程长时间运行而不调用会抛InterruptedException异常的方法会怎样?那它必须周期性地调用Thread.interrupted()方法,该方法在接收到中断请求后返回true。例如:

Java代码 复制代码
  1. for (int 0inputs.length; i++)  
  2.     heavyCrunch(inputs[i]);  
  3.     if (Thread.interrupted())  
  4.         // We've been interrupted: no more crunching.  
  5.         return 
  6.      
  7.  
for (int i = 0; i < inputs.length; i++) {    heavyCrunch(inputs[i]);    if (Thread.interrupted()) {        // We've been interrupted: no more crunching.        return;    }}


在这个简单的例子中,代码只是检测中断,并在收到中断后退出线程。在更复杂的应用中,抛出一个InterruptedException异常可能更有意义。

Java代码 复制代码
  1. if (Thread.interrupted()){  
  2.    throw new InterruptedException();  
  3.  
if (Thread.interrupted()){   throw new InterruptedException();}


这使得中断处理代码能集中在catch语句中。

中断状态标记

中断机制通过使用称为中断状态的内部标记来实现。调用Thread.interrupt()设置这个标记。当线程通过调用静态方法Thread.interrupted()检测中断时,中断状态会被清除。非静态的isInterrupted()方法被线程用来检测其他线程的中断状态,不改变中断状态标记。

按照惯例,任何通过抛出一个InterruptedException异常退出的方法,当抛该异常时会清除中断状态。不过,通过其他的线程调用interrupt()方法,中断状态总是有可能会立即被重新设置。

Joins

Join()方法可以让一个线程等待另一个线程执行完成。若t是一个正在执行的Thread对象,

Java代码 复制代码
  1. t.join();  
t.join();


将会使当前线程暂停执行并等待t执行完成。重载的join()方法可以让开发者自定义等待周期。然而,和sleep()方法一样join()方法依赖于操作系统的时间处理机制,你不能假定join()方法将会精确的等待你所定义的时长。
如同sleep()方法,join()方法响应中断并在中断时抛出InterruptedException。

一个简单的线程例子

下面这个简单的例子将会把这一节的一些概念放到一起演示。SimpleThreads程序有两个线程组成,第一个是主线程,它从创建了一个线程并等待它执行完成。如果MessageLoop线程执行了太长时间,主线程将会将其中断。
MessageLoop现场将会打印一系列的信息。如果中断在它打印完所有信息前发生,它将会打印一个特定的消息并退出。

Java代码 复制代码
  1. public class SimpleThreads  
  2.   
  3.     // Display message, preceded by  
  4.     // the name of the current thread  
  5.     static void threadMessage(String message)  
  6.         String threadName  
  7.             Thread.currentThread().getName();  
  8.         System.out.format("%s: %s%n" 
  9.                           threadName,  
  10.                           message);  
  11.      
  12.   
  13.     private static class MessageLoop  
  14.         implements Runnable  
  15.         public void run()  
  16.             String importantInfo[]  
  17.                 "Mares eat oats" 
  18.                 "Does eat oats" 
  19.                 "Little lambs eat ivy" 
  20.                 "A kid will eat ivy too"  
  21.             };  
  22.             try  
  23.                 for (int 0 
  24.                      importantInfo.length;  
  25.                      i++)  
  26.                     // Pause for seconds  
  27.                     Thread.sleep(4000);  
  28.                     // Print message  
  29.                     threadMessage(importantInfo[i]);  
  30.                  
  31.             catch (InterruptedException e)  
  32.                 threadMessage("I wasn't done!");  
  33.              
  34.          
  35.      
  36.   
  37.     public static void main(String args[])  
  38.         throws InterruptedException  
  39.   
  40.         // Delay, in milliseconds before  
  41.         // we interrupt MessageLoop  
  42.         // thread (default one hour).  
  43.         long patience 1000 60 60 
  44.   
  45.         // If command line argument  
  46.         // present, gives patience  
  47.         // in seconds.  
  48.         if (args.length 0 
  49.             try  
  50.                 patience Long.parseLong(args[0]) 1000 
  51.             catch (NumberFormatException e)  
  52.                 System.err.println("Argument must be an integer.");  
  53.                 System.exit(1);  
  54.              
  55.          
  56.   
  57.         threadMessage("Starting MessageLoop thread");  
  58.         long startTime System.currentTimeMillis();  
  59.         Thread new Thread(new MessageLoop());  
  60.         t.start();  
  61.   
  62.         threadMessage("Waiting for MessageLoop thread to finish");  
  63.         // loop until MessageLoop  
  64.         // thread exits  
  65.         while (t.isAlive())  
  66.             threadMessage("Still waiting...");  
  67.             // Wait maximum of second  
  68.             // for MessageLoop thread  
  69.             // to finish.  
  70.             t.join(1000);  
  71.             if (((System.currentTimeMillis() startTime) patience)  
  72.                   && t.isAlive())  
  73.                 threadMessage("Tired of waiting!");  
  74.                 t.interrupt();  
  75.                 // Shouldn't be long now  
  76.                 // -- wait indefinitely  
  77.                 t.join();  
  78.              
  79.          
  80.         threadMessage("Finally!");  
  81.      
  82.  
public class SimpleThreads {    // Display a message, preceded by    // the name of the current thread    static void threadMessage(String message) {        String threadName =            Thread.currentThread().getName();        System.out.format("%s: %s%n",                          threadName,                          message);    }    private static class MessageLoop        implements Runnable {        public void run() {            String importantInfo[] = {                "Mares eat oats",                "Does eat oats",                "Little lambs eat ivy",                "A kid will eat ivy too"            };            try {                for (int i = 0;                     i < importantInfo.length;                     i++) {                    // Pause for 4 seconds                    Thread.sleep(4000);                    // Print a message                    threadMessage(importantInfo[i]);                }            } catch (InterruptedException e) {                threadMessage("I wasn't done!");            }        }    }    public static void main(String args[])        throws InterruptedException {        // Delay, in milliseconds before        // we interrupt MessageLoop        // thread (default one hour).        long patience = 1000 * 60 * 60;        // If command line argument        // present, gives patience        // in seconds.        if (args.length > 0) {            try {                patience = Long.parseLong(args[0]) * 1000;            } catch (NumberFormatException e) {                System.err.println("Argument must be an integer.");                System.exit(1);            }        }        threadMessage("Starting MessageLoop thread");        long startTime = System.currentTimeMillis();        Thread t = new Thread(new MessageLoop());        t.start();        threadMessage("Waiting for MessageLoop thread to finish");        // loop until MessageLoop        // thread exits        while (t.isAlive()) {            threadMessage("Still waiting...");            // Wait maximum of 1 second            // for MessageLoop thread            // to finish.            t.join(1000);            if (((System.currentTimeMillis() - startTime) > patience)                  && t.isAlive()) {                threadMessage("Tired of waiting!");                t.interrupt();                // Shouldn't be long now                // -- wait indefinitely                t.join();            }        }        threadMessage("Finally!");    }}

0 0