创建线程的常用方法--Java学习笔记

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44494648/article/details/99620210

以前的程序,只有main()方法一个执行流程,按顺序执行main()方法中的语句,这种简单的一个流程,不能满足现在的需求,考虑是否可以创建多个互不相干的流程,同时做不同的操作呢?这就是多线程的思想。
一共有三种方法,第三种作为了解,第二种使用最多

创建线程

1、继承Thread类创建线程

  • 创建一个类,继承Thread类
  • 重写run方法,将想要和主线程同时执行的逻辑代码写进去
  • 创建这个类的对象
  • 启动线程

分部讲解
创建了一个继承Thread的类,并且重写了run()方法

//这里创建了一个继承Thread的类,并且重写了run()方法
class Thread01 extends Thread{
    public void run(){
        for(int i=0;i<=10;i++){
            System.out.println("线程2:"+i);
        }
    }
}
public class Demo03 {
   //main()方法就是主线程的执行体 
    public static void main(String[] args) {
    创建一个对象,并且,调用他的start方法,启动另一个线程
        new Thread01().start();这时候Thread01()中的run()方法和main方法同时执行
       for(int i=0;i<=10;i++){
           System.out.println("主线程:"+i);
       }
    }
}

输出结果

主线程:0
线程2:0
线程2:1
线程2:2
线程2:3
线程2:4
主线程:1
线程2:5
主线程:2
线程2:6
主线程:3
线程2:7
线程2:8
线程2:9
主线程:4
线程2:10
主线程:5
主线程:6
主线程:7
主线程:8
主线程:9
主线程:10

可以看到,两个方法交替这输出,两个线程是并行的

2、实现Runnable接口

  • 创建一个类,实现Runnable接口,重写run方法
  • 创建一个Thread()对象,传入一个实现Runna接口的类的对象
  • 调用Thread的star方法启动线程

分布实现
创建一个类,实现Runnable接口,重写run方法

class Thread02 implements Runnable{
    @Override
    public void run() {
        for(int i=0;i<=10;i++){
            System.out.println("线程3:"+i);
        }
    }
}

创建一个Thread()对象,传入一个实现Runna接口的类的对象

public class Demo03 {
    public static void main(String[] args) {
      //这里是静态代理模式
        new Thread(new Thread02()).start();
       for(int i=0;i<=10;i++){
           System.out.println("主线程:"+i);
       }
    }
}

输出结果

主线程:0
线程3:0
主线程:1
线程3:1
主线程:2
主线程:3
主线程:4
线程3:2
主线程:5
线程3:3
主线程:6
主线程:7
主线程:8
线程3:4
主线程:9
线程3:5
主线程:10
线程3:6
线程3:7
线程3:8
线程3:9
线程3:10

注:上面代码中:new Thread(new Thread02()).start();使用静态代理模式,可以使用Lambda表达式简化代码
详细的看:Lambda表达式(1)

分析

对于上面两种创建方式,
第一种,继承Thread方法:由于Java中是单继承,所以这个类就不能继承其他类,有很大的局限性,但编写简单,要访问当前线程时,不用Thread.currentThread()获得当前线程对象
第二种,这种实现接口的方法就解决了继承冲突的问题,并且可以实现多个线程共享同一个实现Runna接口的类的对象,适合多个线程处理同一个资源,但时编写比较麻烦
但是这两种方法都有一个缺点,那就是run方法没有返回值,不能传参数,不能声明异常因为接口已经限制了run 方法,所以还有一种不常用的创建现成的方法

3、使用Callable 和Future创建线程

Callable接口很类似于Runna 接口其中提供了一个更强大的方法,call方法,call有返回值,可以声明异常,但是它不能直接传入Thread中。因此还要用到另一个接口Future接口;
步骤如下:

  1. 创建一个Callable接口的实现类,并实现call()方法,在创建Callable实现类的实例对象
  2. 使用FutureTask来包装Callable的对象,FutureTask对象封装了Callable对象的call方法的返回值
  3. 使用FutureTask对象作为Thread的targe创建并启动线程
  4. 调用FutureTask的get()方法获取子线程执行结束的返回值,会有阻塞
//了解部分
public class Demo04 {
    public static void main(String[] args) {
        FutureTask<Integer> task=new FutureTask<Integer>(
                ()->{
                    int i=0;
                    for(;i<=10;i++){
                        System.out.println("线程4:"+i);
                    }
                   return i;
                }
        );
        new Thread(task).start();
        for(int i=0;i<=10;i++){
            System.out.println("主线程:"+i);
        }
//获取返回值使用get();
        try {
            System.out.println(task.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

输出结果

主线程:0
主线程:1
线程4:0
线程4:1
主线程:2
线程4:2
线程4:3
线程4:4
线程4:5
线程4:6
线程4:7
线程4:8
线程4:9
线程4:10
主线程:3
主线程:4
主线程:5
主线程:6
主线程:7
主线程:8
主线程:9
主线程:10
11

猜你喜欢

转载自blog.csdn.net/weixin_44494648/article/details/99620210