zoukankan      html  css  js  c++  java
  • java实现多线程的方式(三种)

    最近在学习java多线程,在这里记录一下实现多线程的方式:

    1.继承Tread类,重写run方法:

    public class TheadTest01 {
        public static void main(String[] args) {
            for (int i = 0; i < 10; i++) {
                // 使用start方法开启线程
                new MyThread(i).start();
            }
        }
    }
    
    // 继承Thread类
    class MyThread extends Thread {
        private int i;
    
        public MyThread(int i) {
            this.i = i;
        }
    
        // 重写run方法
        @Override
        public void run() {
            System.out.print(i + " ");
        }
    }
    

    2.实现Runnable接口,重写run方法:

    public class RunnableTest01 {
    
        public static void main(String[] args) {
            for (int i = 0; i < 10; i++) {
                Runnable ra = new MyRunnable(i);
                // 通过Thread的构造函数传入参数,使用start方法开启线程
                new Thread(ra).start();
            }
        }
    
    }
    
    // 实现Runnable接口
    class MyRunnable implements Runnable {
    
        private int i;
    
        public MyRunnable(int i) {
            this.i = i;
        }
    	
    	// 实现run方法
        @Override
        public void run() {
            System.out.println(i);
        }
    
    }
    

    这里需要将Runnable对象当做参数通过构造函数传入创建的Thread对象中,这里简单看一下Thread类的源码:

    public class Thread implements Runnable
    

    首先可以看到Thread类也实现了Runnable接口,再看一下Thread的run方法:

    	@Override
        public void run() {
            if (target != null) {
                target.run();
            }
        }
    

    可以发现,Thread类的run方法只是运行传入Runnable对象的run方法,自身没有做过多实现。

    3.实现Callable接口,重写call方法:

    public class CallableTest01 {
        public static void main(String[] args) throws Exception {
            for (int i = 0; i < 10; i++) {
                // 创建Callable对象
                Callable<Integer> ca = new MyCallable(i);
                // 创建FutureTask对象,并通过构造函数将Callable对象传入
                FutureTask<Integer> future = new FutureTask<Integer>(ca);
                // 创建Thread对象,将FutureTask对象当做参数传入,通过start方法启动线程
                // Runnable ra = future;
                // new Thread(ra).start();
                new Thread(future).start();
            }
        }
    }
    
    // 实现Callable接口
    class MyCallable implements Callable<Integer> {
        private int i;
    
        public MyCallable(int i) {
            this.i = i;
        }
    
        // 重写call方法
        @Override
        public Integer call() throws Exception {
            System.out.println(i);
            return i;
        }
    }
    

    可以发现,使用Callable接口实现多线程,需要将Callable对象通过构造函数传入创建的FutureTask对象中,然后将FutureTask对象通过构造函数传入Thread对象中,才能运行。通过观察Thread的构造函数发现并不能接受FutureTask类型的参数,为什么还能传入呢?这是因为FutureTask类实现了Runnable接口:

    public class FutureTask<V> implements RunnableFuture<V>
    
    public interface RunnableFuture<V> extends Runnable, Future<V>
    

    所以Thread类可以接受FutureTask作为构造参数,类似于:

    Runnable ra = future;
    new Thread(ra).start();
    

    使用Callable接口实现多线程还是可以获取返回值的,使用FutureTask对象的get方法即可,不过如果对每个FutureTask对象直接使用get方法的话,会因为阻塞而不能实现多线程的效果,这时可以通过集合搜集FutureTask对象,然后调用get方法,代码如下:

    public static void main(String[] args) throws Exception {
            // 创建FutureTask<Integer>集合
            List<FutureTask<Integer>> list = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                // 创建Callable对象
                Callable<Integer> ca = new MyCallable(i);
                // 创建FutureTask对象,并通过构造函数将Callable对象传入
                FutureTask<Integer> future = new FutureTask<Integer>(ca);
                // 将FutureTask对象放入集合中
                list.add(future);
                // 创建Thread对象,将FutureTask对象当做参数传入,通过start方法启动线程
                new Thread(future).start();
                // 不能实现异步
                // System.out.println(future.get());
            }
    
            // 使用FutureTask对象的get方法获取返回值
            int result = 0;
            for (int i = 0, len = list.size(); i < len; i++) {
                result += list.get(i).get();
            }
            System.out.println("
    result=" + result);
        }
    
    一颗安安静静的小韭菜。文中如果有什么错误,欢迎指出。
  • 相关阅读:
    Hive扩展功能(四)--HiveServer2服务
    Hive扩展功能(三)--使用UDF函数将Hive中的数据插入MySQL中
    Hive扩展功能(二)--HWI接口
    Hive扩展功能(一)--Parquet
    Flutter全局变量设置 (ScopedModel)
    PHP时间常用方法
    用iFrame Resizer解决iframe高度自适应问题
    aos.js超赞页面滚动元素动画jQuery动画库
    Jcrop最新手册
    jQuery Jcrop API参数说明(中文版)
  • 原文地址:https://www.cnblogs.com/c-Ajing/p/13448373.html
Copyright © 2011-2022 走看看