• java中多线程实现方式


      java中线程是经常会提到的问题,但是实际开发工作却又很少用的技术(起码本人用的比较少)。下面介绍几种常见的线程实现方式

      1、继承Thread类,重写run方法

       我们通过集成Thread类并通过重写run方法的方式实现线程,然后通过start方法启动线程

      

    public class MyThread extends Thread{
    
        @Override
        public void run() {
            System.out.println("================"+new Date());
        }
    
        public static void main(String[] args) {
            for(int i=0;i<10;i++){
                MyThread myThread = new MyThread();
                myThread.start();
            }
        }
    }

    运行main方法测试效果:

      2、通过实现Runable接口的方式

      Thread作为java中的线程类,其有一个Runable作为构造参数的构造方法,我们可以通过实现Runable接口,从而进一步实现线程。同样是通过start启动线程。

    /**
     * 通过实现Runable接口
     */
    public class MyRunableImpl implements Runnable{
    
        private String name;
    
        public MyRunableImpl(String name) {
            this.name = name;
        }
    
        @Override
        public void run() {
            System.out.println(name+"================"+new Date());
        }
    
        public static void main(String[] args) {
            for(int i=0;i<10;i++){
                MyRunableImpl myRunable = new MyRunableImpl("myRunable"+i);
                Thread t = new Thread(myRunable);
                t.start();
            }
        }
    }

    运行main方法测试效果:

       3、通过FutureTask实现线程

      此方式和第二种方式有点像,还是使用Thread(Runnable)构造方法,区别在于此处不用自己实现Runable,而是使用FutureTask。FutureTask实现了

    RunnableFuture接口,而RunnableFuture接口又集成了Runable接口,所以我们也可以使用FutureTask做为构造参数创建线程。FutureTask支持两种有参的构造方法,此处我们使用Future(Callable)。首先,我们需要创建一个类,该类需要实现Callable接口,实现call方法。

    public class MyCallable implements Callable {
    
        private String name;
    
        public MyCallable(String name) {
            this.name = name;
        }
    
        @Override
        public Object call() throws Exception {
            System.out.println(name+"==============="+new Date());
            return name;
        }
    }

    测试类

    public class FutureTaskTest {
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            for(int i=0;i<10;i++){
                MyCallable myCallable = new MyCallable("myCallable"+i);
                FutureTask futureTask = new FutureTask(myCallable);
                Thread t = new Thread(futureTask);
                t.start();
                Object o = futureTask.get();
                System.out.println("return value============"+o);
            }
        }
    }

    运行main方法测试效果:

     在线程启动时会调用Callable接口的call方法。我们可以通过FutureTask.get()方法获取call()的返回值。需要注意的是get方法会阻塞线程。

      4、使用Executors创建线程池

      Executors是java juc中的类,我们可以通过其创建线程池,并以此实现线程。此方式同样需要一个Callable的实现类,此处我们还是使用第3中方法中的类。

    public class ExecutorsTest {
    
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            List<Future<?>> list = new ArrayList<>();
            for(int i=0;i<10;i++){
                MyCallable myCallable = new MyCallable("myCallable"+i);
                Future submit = executorService.submit(myCallable);
                list.add(submit);
            }
            for(Future future:list){
                try {
                    Object o = future.get();
                    System.out.println("return value============="+o);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
            executorService.shutdown();
        }
    }

    我们通过Executors创建线程池,ExecutorService.submit(Callable)启动线程。submit方法会返回一个Future对象,通过其get()方法可以获取Callable实现类的call方法返回值。执行完上述操作后需要调用ExecutorService.shutdown方法,不然主线程会一直处于运行状态。

    执行main方法测试效果:

     以上就是常见的创建多线程的几种方式。如果不对,对应大家评论留言。

  • 相关阅读:
    Dubbo的使用入门
    Centos7安装Tomcat并部署DubboAdmin的War包并配置自动启动
    JPA中自动使用@Table(name = "userTab")后自动将表名、列名添加了下划线的问题
    JAVA和C#检测IP地址段是否交叉和获取地址段IP列表的方法
    MySQL中的insert ignore into, replace into用法总结
    SpringBootWEB项目和非Web项目的全局异常捕获
    SpringBoot中配置起动时的数据库初始化角本
    树莓派中编译Opencv3.4.1和OpenCVSharp库
    树莓派简单摄像头录像并保存视频文件
    树莓派中编译OpenCV3.4.1和OpenCvSharp
  • 原文地址:https://www.cnblogs.com/xiupan/p/12702267.html
Copyright © 2020-2023  润新知