• Java多线程的不同实现方式


    5种创建方式:

    • 继承Thread类
    • 实现Runnable接口
    • 使用匿名内部类方式
    • 实现Callable接口
    • 使用线程池的方式

    1. 继承Thread类
    Thread类本质上是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。

    public class multiThreading1 extends Thread{
        public void run(){
            System.out.println("111");
        }
        public static void main(String[] args) {
            multiThreading1 m1 = new multiThreading1();
            m1.start();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2. 实现Runnable接口
    实现Runnable接口的多线程要启动需要先实例化一个Thread,然后传入自己的实现Runnable接口的类的实例。
    事实上,当传入一个Runnable target参数给Thread后,Thread的run()方法就会调用target.run()。

    public class multiThreading2 implements Runnable{
        //重写run方法
        @Override
        public void run() {
            System.out.println("22222");
        }
        public static void main(String[] args) {
            //实例化一个Thread,然后传入multiThreading2类的实例
            Thread thread = new Thread(new multiThreading2());
            thread.start();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3. 使用匿名内部类方式

    public class MyThread {
        public static void main(String[] args) {
            //第一种相当于继承Thread类,通过子类的方式来实现
            new Thread("匿名内部类1"){
                @Override
                public void run(){
                    System.out.println(Thread.currentThread().getName()+"33");
                }
            }.start();
            //第二种将实现Runnable接口的类作为参数传进去
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"44");
                }
            },"匿名内部类2").start();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    4. 实现Callable接口
    实现Callable接口是有返回值的,实现call接口,相比于Runnable接口是没有返回值的,这是两者的区别。使用该方法的一些步骤:
    ①创建Callable接口的实现类 ,并实现Call方法
    ②创建Callable实现类的实例对象
    ③创建FutureTask类的实例对象,通过FutureTask类包装Callable对象,该FutureTask的实例对象封装了Callable对象的Call方法的返回值
    ④创建Thread对象,使用FutureTask对象作为Thread对象的target创建并启动线程
    ⑤调用FutureTask对象的get()来获取子线程的返回值

    public class multiThreading3 implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            System.out.println("Callable正在计算...");
            Thread.sleep(3000);
            return 1;
        }
        public static void main(String[] args) throws Exception {
            //创建Callable实现类的实例
            multiThreading3 threading3 = new multiThreading3();
            //使用FutureTask类包装Callable对象
            FutureTask<Integer> futureTask = new FutureTask<>(threading3);
            //创建Thread对象
            Thread thread = new Thread(futureTask);
            thread.start();
            //调用FutureTask对象的get()来获取子线程的返回值
            Integer result = futureTask.get();
            System.out.println("结果为:" + result);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    5. 使用线程池的方式
    从java5开始,提供了一系列工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口。

    public class multiThreading4 {
    
        //定义线程池数量
        private static int POOL_NUM = 10;
    
        public static void main(String[] args) {
            //创建线程池
            ExecutorService executorService = Executors.newFixedThreadPool(5);
            for (int i = 0; i < POOL_NUM; i++) {
                //执行线程
                executorService.execute(new RunnableThread());
            }
            //关闭线程池
            executorService.shutdown();
        }
    }
    class RunnableThread implements Runnable{
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
  • 相关阅读:
    GlusterFS企业分布式存储
    synchronized和lock的区别
    pointnet和pointnet++点云分割和分类
    Linux CentOS配置阿里云yum源
    接口自动化之测试数据动态生成并替换
    【蓝桥杯选拔赛真题03】C++输出字母Y 青少年组蓝桥杯C++选拔赛真题 STEMA比赛真题解析
    遗传算法(GA)学习 || 原理、本质、代码、例题
    C#实现本地服务器客户端私聊通信
    【TA-霜狼_may-《百人计划》】图形3.7.2 command buffer简
    centos7中卸载Java、jdk命令
  • 原文地址:https://blog.csdn.net/yangen2018/article/details/126543030