美文网首页
【多线程入门系列一】线程的创建,启动与停止

【多线程入门系列一】线程的创建,启动与停止

作者: 5d44bc28b93d | 来源:发表于2018-02-09 17:22 被阅读11次
ceHJJ2KACQh.jpg

多线程入门系列(一) 线程的基本知识

线程的创建

  1. 继承Thread类
 public class MyThread  extends Thread{
  @Override
  public void run() {
      super.run();
      System.out.println("Hello MyThread");
  }
}
  1. 实现Runnable接口
public class MyRunnableThread implements Runnable {

  @Override
  public void run() {
      System.out.println("Hello MyRunnableThread");
  }
}
  1. 实现Callable接口
class MyCallable implements Callable<String>{

  @Override
  public String call() throws Exception {
      Thread.sleep(10000);
      return "回调成功";
  }
}

public class Main {


  public static void main(String[] args) {
      MyCallable myCallable = new MyCallable();
      FutureTask<String> futureTask1 = new FutureTask<String>(myCallable);
      ExecutorService executor = Executors.newFixedThreadPool(2);        // 创建线程池并返回ExecutorService实例
      executor.execute(futureTask1);
      while(true){
          if(futureTask1.isDone()){
              try {
                  System.out.println(futureTask1.get());
                  break;
              } catch (InterruptedException e) {
                  e.printStackTrace();
              } catch (ExecutionException e) {
                  e.printStackTrace();
              }
          }else{
              System.out.println("等待中。。。");
          }
      }
  }
  1. 总结对比

    • 使用继承的方式来开发多线程应用程序在设计上存在局限性。因为Java不支持多继承。而为了改变这一限制我们可以采用实现Runnable的方式。
    • Callable与其他两种的区别在于当线程执行完毕后可以接受返回值。

线程的启动

  1. start 方法
  • 继承Thread类的启动方法

    public class Run {
      public static void main(String[] args) {
          MyThread thread = new MyThread();
          thread.start();
          Thread thread3 = new Thread(new MyThread());
          thread3.start();
      }
     }
    
  • 实现Runnable接口启动方式

    class Run {
     public static void main(String[] args) {
         Thread thread = new Thread(new MyRunnableThread());
         thread.start();
     }
     }
    
    
    1. run 方法
    public class Run {
     public static void main(String[] args) {
         MyThread thread = new MyThread();
         thread.run();
     }
    }  
    
    1. 总结
    • start方法与run方法对比

      • 线程调用start方法通知“线程规划器”当前线程已经做好准备,此过程其实就是通知系统安排一个时间来执行线程的run方法,此过程是异步的。
      • 直接调用run方法则是同步的,与我们平常调用一个类的方法没有任何区别。
    • 启动方式

      • Thread类的构造方法中可以传递Thread对象,这意味着可以将一个线程的run方法交给另一个线程去执行
      • Thread类构造能支持传递Runnable接口,这避免的java单继承的局限性

优雅的停止线程


  • 使用中断标志使线程停止

    • 下文中interrupt停止方法就是一种按照线程标志位停止线程的方式。另外也可以使用自己设置的标志位来停止线程此处不再赘述。
  • 使用stop强行终止线程(方法已过时不推荐)

    • stop停止线程是调用stop方法来暴力停止线程,这个方法已经过时不推荐使用,且在调用stop方法是会释放锁造成数据不一致的结果。
  • 使用interrupt方法终止线程

    • 判断线程是否终止状态

      • interrupted 与 isInterrupted

        • interrupted 检测当前线程是否中断 具有清除状态的功能。
        • isInterrupted 检测线程是否中断
      • 举例说明:

        ```java
        public class MyThread extends Thread {
            @Override
            public void run() {
                super.run();
                while(true){
                }
            }
            }
        class Run {
            public static void main(String[] args) {
                MyThread thread = new MyThread();
                thread.start();
                thread.interrupt();
                System.out.println(thread.interrupted());
                System.out.println(thread.isInterrupted());
                Thread.currentThread().interrupt();
                System.out.println(
                    Thread.currentThread().isInterrupted()
                    );
                System.out.println(
                    Thread.currentThread().interrupted()
                    );
                System.out.println(
                    Thread.currentThread().interrupted()
                    );
            
            }
        
        ```
  * 前面两个输出分别为false,true,因为interrupted检测当前线程是否中断,而当前线程为main方法的主线程并且并未中断所以为false,而isInterrupted则检测线程是否中断,可以看出线程调用了interrupt方法确实是使其中断标志位为true,细心的可以发现如果在while循环里面加上打印输出,interrupt方法并没有真正的中断线程,仅仅的修改了标志位。
  * 后面三个输出分别为true true false ,最后一个输出为false是因为interrupted调用后重置了标志位。
  • interrupt方式中断线程

    • 例子01:

       ```java
       public class MyThread extends Thread {
       @Override
       public void run() {
           super.run();
           for (int i = 0; i < 500000; i++) {
               System.out.println("运行中");
               if(this.isInterrupted()){
                   break;
               }
           }
           System.out.println("结束运行");
           }
       }
       class Run {
           public static void main(String[] args) {
               MyThread thread = new MyThread();
               thread.start();
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               thread.interrupt();
      
           }
       }
       ```
      
    • 异常法中断线程

      • 例子02:
      public class MyThread extends Thread {
          @Override
          public void run() {
              super.run();
              try {
                  for (int i = 0; i < 500000; i++) {
                      System.out.println("运行中");
                      if (this.isInterrupted()) {
                          throw new InterruptedException();
                      }
                  }
                  System.out.println("end");
              } catch (InterruptedException e) {
                  System.out.println("进入catch");
                  e.printStackTrace();
              }
          }
      }
      class Run {
          public static void main(String[] args) {
              MyThread thread = new MyThread();
              thread.start();
              try {
                  Thread.sleep(500);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              thread.interrupt();
      
          }
      }
      

      小结:

      • 例子01的方式不能很好的关闭线程,如果在break后循环终止,但是循环后面的代码将会继续执行,这样并没有起到停止线程的目的
      • 例子02在原有的基础上进行改进利用异常法中断线程。只要try方法块中抛出异常,则线程就会终止。
  • 使用return停止线程

    • 此处可以使用上面interrupt例子01的方式,将break语句改为return
  • 在休眠中停止线程

    • 休眠之前停止线程
    ```java
    public class MyThread extends Thread {
    @Override
    public void run() {
        super.run();
        try {
            for (int i = 0; i < 500000; i++) {
                System.out.println("运行中");

            }
            Thread.sleep(1000);
            System.out.println("end");
        } catch (InterruptedException e) {
            System.out.println("进入catch" + this.isInterrupted());
            e.printStackTrace();
        }
    }
     }

    class Run {
        public static void main(String[] args) {

            try {
                MyThread thread = new MyThread();
                thread.start();
                Thread.sleep(500);
                thread.interrupt();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }


        }
    }
    ```
  • 休眠之后停止线程

    public class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            try {
                Thread.sleep(3000);
                for (int i = 0; i < 500000; i++) {
                    System.out.println("运行中");
                }
                System.out.println("end");
            } catch (InterruptedException e) {
                System.out.println("进入catch" + this.isInterrupted());
                e.printStackTrace();
            }
        }
    }
    
    class Run {
        public static void main(String[] args) {
    
            try {
                MyThread thread = new MyThread();
                thread.start();
                Thread.sleep(500);
                thread.interrupt();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
    • 小结:

      通过打印输出可以发现这两种方式在休眠前与休眠后中断线程的结果是不一样的,

      • 休眠前后中断线程线程的isInterrupt方法输出为false即在休眠时或者碰到休眠而终止线程会重置线程的状态。区别在于,休眠前中断是先标记为中断状态,然后碰到sleep方法时终止。休眠后中断则会立马出发终止并且重置状态

相关文章

  • 【多线程入门系列一】线程的创建,启动与停止

    多线程入门系列(一) 线程的基本知识 线程的创建 继承Thread类 实现Runnable接口 实现Callabl...

  • Java多线程(二)

    Java多线程(二) 上一篇“Java多线程(一)”主要讨论的是线程的创建,本章主要讨论停止线程。 1.概述 停止...

  • java多线程--Callable

    **移步[java多线程系列文章]Java多线程(二十二)---LockSupport工具Java 停止线程 一、...

  • Java 多线程之线程的创建及其使用

    一、创建线程以及启动线程 二、停止线程 三、线程类中函数详解 一、创建线程以及启动线程 创建线程:Java中创建线...

  • Twisted 入门

    Twisted 入门 在多线程程序中,对于停止某个线程启动另外一个线程,其决定权并不在程序员手里而在操作系统那里。...

  • iOS开发-多线程NSThread的基本介绍和使用

    今天给同学讲解一下多线程的入门了解和使用那么废话不多说直接上代码~ NSThread创建和启动线程 NSThrea...

  • 2019-01-21

    基于多线程解析 多线程原理 创建线程一: 程序启动运行main时候,java虚拟机启动一个进程,主线程main在m...

  • 高并发(3)- 多线程的停止

    前言 上篇文章讲解了多线程的两种创建方法,那么本文就带来多线程的停止方法。 一、线程的停止 1.stop方法 st...

  • GCD

    多线程 NSTheard :alloc init 方法创建线程 。 start 方法启动线程 。然后系统会管理线程...

  • 多线程深入话题

    优雅的停止线程 在多线程操作之中如果要启动多线程,肯定要使用Thread类中的start()方法,而如果对于对线程...

网友评论

      本文标题:【多线程入门系列一】线程的创建,启动与停止

      本文链接:https://www.haomeiwen.com/subject/cpfqtftx.html