初识多线程

初识多线程

简介

  • 何为线程

    • 程序是指令和数据的集合
    • 进程是计算机分配资源的单位
    • 线程是CPU调度和执行的单位
  • 多线程的优势

    • 能够充分利用CPU性能,在执行一些高延时的操作时,进行其他任务而不是等待

多线程的创建方式

通过 Thread 类派生子类实现多线程

  • 具体步骤

    • 派生 Thread 子类

    • 覆写 run 方法

    • 调用 start 方法

      class Test{
          public static void main(String[] args){
              Thread t = new MyThread();
              t.start();
              System.out.println("主线程...");
          }
      }
      
      class MyThread extends Thread{
          @Override
          public void run(){
              System.out.println("子线程...");
          }
      }
      
    • 关于参数传递的案例

      public class ExtendsThread extends Thread{
          private String name;
      
          public ExtendsThread(String name){
              this.name = name;
          }
      
          // 继承Thread 覆写run方法
          @Override
          public void run(){
              for (int i = 0; i < 10; i++){
                  System.out.println(name + i);
              }
          }
      
          public static void main(String[] args) {
              // 创建派生线程类实例,调用start()方法
              Thread t = new ExtendsThread("子线程");
              t.start();
              System.out.println("主线程end...");
          }
      }
      
      • 综合来说是不建议使用这种方式来创建多线程的,因为单继承的局限性

通过实现Runnable 接口

  • 具体步骤

    • 实现 Runnable 接口

    • 覆写 run 方法

    • 将变量作为参数,通过Thread静态代理执行start()方法

      代理模式 - Rainful - 博客园 (cnblogs.com)

      public class ImpRunnable implements Runnable{
          @Override
          public void run(){
              for (int i = 0; i < 10; i++){
                  System.out.println(Thread.currentThread().getName() + i);
                  try {
                      Thread.sleep(100);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          }
      
          public static void main(String[] args) {
              // 创建多个实例
              ImpRunnable t = new ImpRunnable();
      
              new Thread(t, "1线程").start();
              new Thread(t, "2线程").start();
              new Thread(t, "3线程").start();
          }
      }
      
    • 多个线程同时访问单一对象

      public class ImpRunnable2 implements Runnable{
          private int num = 10;
      
          @Override
          public void run(){
              while (num > 0){
                  System.out.println(Thread.currentThread().getName() + num--);
                  try {
                      Thread.sleep(100);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          }
      
          public static void main(String[] args) {
              ImpRunnable2 num = new ImpRunnable2();
      
              new Thread(num, "1线程").start();
              new Thread(num, "2线程").start();
              new Thread(num, "3线程").start();
          }
      }
      
      • 实现 Runnable 接口创建多线程,可以使得避免单继承带来的问题,同时也方便多个线程访问同一个对象
      • 这里我们可以看到多线程同时对同一个对象进行操作时产生了数据的异常

通过实现Callable接口

  • 具体步骤

    • 实现Callable接口,自定义返回值类型

    • 覆写call方法,需要抛出异常

    • 创建目标对象

    • 创建执行服务

    • 提交执行

    • 获取结果

    • 关闭服务

      public class ImpCallable implements Callable<Boolean> {
          private String name;
      
          public ImpCallable(String name){
              this.name = name;
          }
      
          @Override
          public Boolean call(){
              for (int i = 0; i < 10; i++){
                  System.out.println(name + i);
                  try {
                      Thread.sleep(1000);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
              return true;
          }
      
          public static void main(String[] args) throws ExecutionException, InterruptedException {
              // 创建线程对象
              ImpCallable t1 = new ImpCallable("1");
              ImpCallable t2 = new ImpCallable("2");
              ImpCallable t3 = new ImpCallable("3");
      
              // 创建执行服务
              ExecutorService ser = Executors.newFixedThreadPool(3);
      
              // 提交执行
              Future<Boolean> r1 = ser.submit(t1);
              Future<Boolean> r2 = ser.submit(t2);
              Future<Boolean> r3 = ser.submit(t3);
      
              // 获取结果
              Boolean rs1 = r1.get();
              Boolean rs2 = r2.get();
              Boolean rs3 = r3.get();
      
              // 关闭服务
              ser.shutdownNow();
          }
      }
      
posted @ 2021-06-19 23:12  Rainful  阅读(33)  评论(0编辑  收藏  举报