• Java多线程的创建(二)


    • 前言:

      虽然java的API中说创建多线程的方式只有两种(There are two ways to create a new thread of execution),分别是继承Thread类创建和实现Runnable接口创建,在上一篇博文中演示了这两种,详见,但是JDK5.0以后新增了两种,分别是实现Callable接口创建和使用线程池创建,本次就演示后两种创建方式并分析其特性。


    • 实现Runnable接口创建多线程

      创建步骤:

      1.创建一个实现Callable接口的类。

      2.重写call()方法,线程需要执行的代码都放到call方法中。

      3.创建实现Callable接口类的实例对象。

      4.将步骤 3 的对象作为参数传给FutureTask构造器中,创建FutureTask对象。

      5.将FutureTask的对象作为参数传给Thread类,创建对象并调用start()方法。

    package day02;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    //创建一个多线程,输出20以内的偶数,并返回所有偶数的和
    //1.创建一个实现`Callable`接口的类。  
    class TestSum implements Callable{
       //2.重写call()方法,线程需要执行的代码都放到call方法中。
        @Override
        public Object call() throws Exception{
            int sum = 0;
            for(int i = 1;i <= 20 ;i++ ){
                if(i % 2 == 0){
                    System.out.println(i);
                    sum = sum + i;
                }
            }
            return sum;
        }
    }
    
    public class ThreadCall {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            //3.创建实现`Callable`接口类的实例对象。
            TestSum test = new TestSum();
            //4.将步骤 3 的对象作为参数传给`FutureTask`构造器中,创建`FutureTask`对象。
            FutureTask futuretask = new FutureTask(test);
            //5.将`FutureTask`的对象作为参数传给`Thread`类,创建对象并调用start()方法。
            Thread thread = new Thread(futuretask);
            thread.start();
            //get方法可以获取返回值
            System.out.println("偶数总合是:"+futuretask.get());
        }
    }
    //输出结果:
    2
    4
    6
    8
    10
    12
    14
    16
    18
    20
    偶数总合是:110
    

    实现Callable接口创建多线程的特点:

    ​ 1.call()方法可以有返回值,可以使用get()方法获取返回值。

    ​ 2.call()方法可以抛出异常, 而且能被外面捕获到。

    ​ 3.Callable支持泛型。


    • 使用线程池创建多线程

      一.实现Runnable接口的方式创建:

    package day02;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    class Number implements Runnable{
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                if (i % 2 == 0){
                    System.out.println(Thread.currentThread().getName()+":"+i);
                }
            }
        }
    }
    
    public class ThreadPool {
        public static void main(String[] args){
            ExecutorService service = Executors.newFixedThreadPool(10);
            Number num = new Number();
            service.execute(num);
            service.shutdown();
    

    二.实现Callable接口的方式创建:

    package day02;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    class Number implements Callable {
        @Override
        public Object call() {
            for (int i = 0; i < 20; i++) {
                if (i % 2 == 0){
                    System.out.println(Thread.currentThread().getName()+":"+i);
                }
            }
            return null;
        }
    }
    
    public class ThreadPool {
        public static void main(String[] args){
            ExecutorService service = Executors.newFixedThreadPool(10);
            Number num = new Number();
            service.submit(num);//区别在这里
            service.shutdown();
        }
    }
    
    
    • 线程池好处:

      1.频繁创建线程和销毁使用量较大的资源,比如并发的线程,对性能影响较大,所以需要创建线 程池存放线程,使用的时候直接获取,实现重复利用,提高效率。

      2.降低创建线程时间,提高响应速度。

      3.降低资源的消耗。

      4.便于线程管理。

  • 相关阅读:
    个人技术博客
    第十七周19年春学习总结
    第十六周第四次实验设计报告
    第十五周第三次实验设计报告
    第十四周第二次试验设计报告
    第十三周
    第十二周
    第十一周
    第十周作业
    只为粗暴看一下ES6的字符串模板的性能
  • 原文地址:https://www.cnblogs.com/coding-996/p/12149965.html
Copyright © 2020-2023  润新知