• 线程的创建终止和生命周期


    1 线程的创建

    方法1:实现Runnable接口(推荐)

    class Runner1 implements Runnable {
        public void run() {
            for(int i=0; i<30; i++) System.out.println("No. " + i);
        }
    }
    public class TestThread1 {
        public static void main(String args[]) {
            Thread t1 = new Thread(new Runner1());
            t1.start();
        }
    }

    Runable是任务的概念,如果我们直接这样写,会怎么样呢?只会在原来的线程(Main的)里执行run方法。可见Runable更灵活,任务不用写死在线程里,可以放到不同的线程,甚至线程池里运行。把任务和运行分离

    public class TestThread1 {
        public static void main(String args[]) {
            Runnable r1 = new Runner1();
            r1.run();
        }
    }

    方法2:继承Thread

    class Thread1 extends Thread {
        public void run() {
            for(int i=0; i<100; i++) {    
                System.out.println("Runner1 :" + i);
            }
        }
    }
    public class TestThread1 {
        public static void main(String args[]) {
            Thread1 t1 = new Thread1();
            t1.start();
        }
    }

    2 线程的终止

    参考:http://www.cnblogs.com/skywang12345/p/3479949.html

    http://hapinwater.iteye.com/blog/310558

      线程的终止主要有三种方式:

      a. interrupt;

      b. 通过额外标识位;

      c. suspend(暂停),resume(恢复),stop(终止),这三个方法已经过时。suspend和resume就像唱片机,能停能恢复,现在主要被wait/notify取代。stop终止线程太暴力,没时间让线程释放资源,所以被淘汰了。

      这些终止是让别的线程终止自己,因别人启动,因别人终止啊~。要终止自己只要从run方法return就行。

    2.1 interrupt

    每个线程上都有一个标识位interrupted,说明该线程是否被中断。当interrupt()时,只会改标志位,不会真的终止线程。我这里加了一个on标识来关掉这个线程,否则我们就没办法关闭它了。

    class ATask  extends Thread { 
        private volatile boolean on=true;
        
        public void run() {
            while (on) {  
                System.out.println("I am running!");                
                for (int i = 0; i < 10000000; i++);
            }  
        }
        
        public void shutdown(){
            on=false;
        }
    }  
      
    public class TestThread {  
          
        public static void main(String[] args) throws Exception{
            ATask t = new ATask();  
            t.start();  
              
            //运行一断时间中断线程  
            Thread.sleep(20);  
            System.out.println("****************************");  
            System.out.println("Interrupted Thread!");  
            System.out.println("****************************");  
            t.interrupt();
            Thread.sleep(20);
            System.out.println("ShutDown Thread!");  
            System.out.println("****************************");  
            t.shutdown();
        }  
    }   

    运行结果:

    I am running!
    I am running!
    ****************************
    Interrupted Thread!
    ****************************
    I am running!
    I am running!
    ShutDown Thread!
    ****************************

      interrupted可以通过myThread.isInterrupted()查询,也可以通过Thread.interrupted()重置interrupted标志位(设为fasle)。

      java给了线程编写者自由,让他定义在别人中断自己时怎么响应。主要分两种情况,一种是阻塞式的,另一种是非阻塞式。

    a. 阻塞式的:调用了sleep(), wait(), join()等方法就会进入阻塞状态。就是说干什么已经不由线程编写者决定,控制权交到sleep里。这些阻塞方法都会抛InterruptedException异常,我么只要在catch里响应Interrupt。可以向下面乖乖地return,就终止了线程(并释放相应资源);也可以直接不管(catch里什么都不写),这样线程就会继续while下去。这里有个小细节,在抛InterruptedException时,虚拟机会重置interrupted标志位。

    class ATask  extends Thread { 
        public void run() {
            while(true){            
                try {
                    System.out.println("I am running!");
                    sleep(1000);
                } catch (InterruptedException e) {
                    System.out.println("ATask.run() interrupted!");
                    return;
                }
            }       
        }  
    } 
    
    
    public class TestThread {
        public static void main(String[] args) throws Exception{  
            //将任务交给一个线程执行  
            Thread t = new ATask();  
            t.start();  
              
            //运行一断时间中断线程  
            Thread.sleep(20);  
            System.out.println("****************************");  
            System.out.println("Interrupted Thread!");  
            System.out.println("****************************");  
            t.interrupt();  
        }
    }

    运行结果:

    I am running!
    ****************************
    Interrupted Thread!
    ****************************
    ATask.run() interrupted!

    b. 非阻塞式方法:不是阻塞式的,控制权在自己手里。

    class ATask  extends Thread { 
        public void run() {  
            //检查程序是否发生中断  
            while (!Thread.interrupted()) {  
                System.out.println("I am running!");
                for (int i = 0; i < 1000000; i++); 
            }
            System.out.println("ATask.run() interrupted!");  
        }  
    } 
    public class TestThread{  
        
        public static void main(String[] args) throws Exception{  
            //将任务交给一个线程执行  
            Thread t = new ATask();  
            t.start();  
              
            //运行一断时间中断线程  
            Thread.sleep(20);  
            System.out.println("****************************");  
            System.out.println("Interrupted Thread!");  
            System.out.println("****************************");  
            t.interrupt();  
        }  
    } 

    运行结果:

    I am running!
    I am running!
    ****************************
    Interrupted Thread!
    ****************************
    ATask.run() interrupted!

    2.2 通过额外标识位

    class ATask  extends Thread {
        private volatile boolean on = true;
        
        public void run() {
            while(on){            
                 System.out.println("I am running!");                
                 for (int i = 0; i < 10000000; i++);
            }
        }
        
        public void shutDown() {
            on = false;
        }
    } 
    
    public class TestThread {
        public static void main(String[] args) throws InterruptedException{  
            //将任务交给一个线程执行  
            ATask t = new ATask();  
            t.start();  
              
            //运行一断时间中断线程  
            Thread.sleep(20);  
            System.out.println("****************************");  
            System.out.println("shutDown Thread!");  
            System.out.println("****************************");  
            t.shutDown();  
        }
    }

    对比2.1,2.2两种方法:

    a 都能 自由地处理其他线程的终止请求;

    b 都能 在终止时释放资源;

    c 2.2不能终止处于阻塞状态的线程。

    3 线程的生命周期

     线程的状态起始很简单,就是启动->运行->终止。等待,超时等待,阻塞都是一种阻塞状态,到用到时在分析,和线程的状态没太多关系,就那么简单。

  • 相关阅读:
    P4365 [九省联考2018]秘密袭击coat
    P3705 [SDOI2017]新生舞会 01分数规划+费用流
    P4313 文理分科 最小割
    P1707 刷题比赛
    P3994 高速公路 树形DP+斜率优化+二分
    P3384 【模板】树链剖分
    P4915 帕秋莉的魔导书
    P3690 【模板】Link Cut Tree (动态树)
    P3615 如厕计划
    loj #2538. 「PKUWC2018」Slay the Spire
  • 原文地址:https://www.cnblogs.com/deliver/p/5678513.html
Copyright © 2020-2023  润新知