• 面试官:小伙子,说一说Java多线程有哪些创建方式吧


    第一种 继承Thread类

    自定义类,继承Thread类,并重写run()方法.

    class MyThread1 extends Thread {
        @Override
        public void run() {
            System.out.println("第一种方式Thread " + Thread.currentThread().getName());
        }
    }
    public class Test {
        public static void main(String[] args) throws Exception {
            //第一种方式
            MyThread1 thread1 = new MyThread1();
            thread1.start();
            
            MyThread1 thread1 = new MyThread1();
            thread1.start();
    
            MyThread1 thread2 = new MyThread1();
            thread2.setName("zz");
            thread2.start();
            // 运行结果
            // 第一种方式Thread Thread-0
            // 第一种方式Thread Thread-1
            // 第一种方式Thread zz
            // 若不指定Name属性,能默认计数器0,1,2,3,4,5
        }
    }
    

      

    第二种 实现Runnable接口

    自定义类,实现Runnable接口的run方法. since JDK1.0

    class MyThread2 implements Runnable {
        @Override
        public void run() {
            System.out.println("第二种方式Runnable " + Thread.currentThread().getName());
        }
    }
    public class Test {
        public static void main(String[] args) throws Exception {
            //第二种方式
            Thread thread2 = new Thread(new MyThread2());
            thread2.start();
            // Lambda表达式方式->因为Runnable被注解FunctionalInterface标识表明该接口是一个函数式接口
            new Thread(() -> {
                System.out.println("第二种方式Runnable_Lambda " + Thread.currentThread().getName());
            }).start();
            // 运行结果
            // 第二种方式Runnable Thread-0
            // 第二种方式Runnable_Lambda Thread-1
        }
    }
    

      

    第三种 实现Callable接口

    已知Runnable的run方法无返回值,所以引入了有返回值的Callable接口
    since JDK1.5

    FutureTask中构造方法如下.

    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }
    

      

    FutureTask类结构图如下.

     
     

    因为FutureTask类实现了Runnable接口,所以线程实现方法如下.

    public class Test {
         public static void main(String[] args) throws Exception {
            //第三种方式
            FutureTask<String> thread3 = new FutureTask<>(new MyThread3());
            new Thread(thread3).start();
            System.out.println(thread3.get()); //获得回调值
            
            FutureTask<String> thread4 = new FutureTask(()->{
                System.out.println("Call");
                return "Lambda回调";
            });
            new Thread(thread4).start();
            System.out.println(thread4.get());
            // 运行结果
            // 第三种方式Callable Thread-0
            // 回调
            // Call
            // Lambda回调
        }
    }
    class MyThread3 implements Callable<String> {
        @Override
        public String call() throws Exception {
            System.out.println("第三种方式Callable " + Thread.currentThread().getName());
            return "回调";
        }
    }
    

      

    第四种 线程池

    交付线程池两种方式 submit或者execute方法,前者可接受Callable接口对象,有返回值,后者无返回值

    public class Test {
        public static void main(String[] args) throws Exception {
            //第一种方式
            MyThread1 thread1 = new MyThread1();
            thread1.start();
            //第二种方式
            Thread thread2 = new Thread(new MyThread2());
            thread2.start();
            //第三种方式
            FutureTask<String> thread3 = new FutureTask<>(new MyThread3());
            new Thread(thread3).start();
            System.out.println(thread3.get());
            //第四种方式
            ExecutorService pool = Executors.newFixedThreadPool(5);
            Future<?> submit1 = pool.submit(new MyThread1());
            Future<?> submit2 = pool.submit(new MyThread2());
            Future<?> submit3 = pool.submit(new MyThread3());
            System.out.println(submit1.get() + " " + submit2.get() + "  " + submit3.get());
            pool.shutdown();
            // 运行结果
            // 第一种方式Thread Thread-0
            // 第二种方式Runnable Thread-1
            // 第三种方式Callable Thread-2
            // 回调
            // 第一种方式Thread pool-1-thread-1
            // 第二种方式Runnable pool-1-thread-2
            // 第三种方式Callable pool-1-thread-3
            // null null  回调
        }
    
    }
    

      

    特点

    无论何种方式,都要使用Thread类中start方法开始多线程.
    Runnable接口和Callable接口区别,后者可返回参数,参数类型Object.
    线程池避免了线程频繁使用的创建和释放操作.

    看完有什么不懂的欢迎在下面留言评论!

  • 相关阅读:
    算法之递归(4) 应用
    算法之递归(1)
    [Async] [Series #1] 初识Async异步编程模型。
    CVE202142287/CVE202142278 复现
    易读文库下载器1.2版发布
    Sqlite.net 读取DateTime异常的解决方案
    QZFL 2.0.5 源代码
    Sqlite 管理工具 SQLiteDeveloper 及破解
    visio2010数据库正向工程生成数据库脚本
    什么是高内聚、低耦合?
  • 原文地址:https://www.cnblogs.com/lwh1019/p/12906557.html
Copyright © 2020-2023  润新知