• 多线程及线程池


    JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。
    1、继承Thread类实现多线程
    继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例,并且,启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。

    package com.test;
    
    public class ThreadDemo {
        public static void main(String[] args) {
            MyThread myThread1 = new MyThread();
            MyThread myThread2 = new MyThread();
            myThread1.start();
            myThread2.start();
        }
    }
    
    class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName());
        }
    }
    

    2、实现Runnable接口方式实现多线程

    如果自己的类已经extends另一个类,就无法直接extends Thread,此时,必须实现一个Runnable接口。

    package com.test;
    
    public class ThreadDemo {
        public static void main(String[] args) {
            MyThread myThread1 = new MyThread();
            MyThread myThread2 = new MyThread();
            Thread thread1 = new Thread(myThread1);
            Thread thread2 = new Thread(myThread2);
            thread1.start();
            thread2.start();
        }
    }
    
    class MyThread implements Runnable {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName());
        }
    }
    

    3、使用ExecutorService、Callable、Future实现有返回结果的多线程

    ExecutorService、Callable、Future这个对象实际上都是属于Executor框架中的功能类。执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了,再结合线程池接口ExecutorService就可以实现传说中有返回结果的多线程了。

    package com.test;
    
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import java.util.concurrent.*;
    
    public class ThreadDemo {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            System.out.println("----程序开始运行----");
            int taskSize = 5;
            // 创建一个线程池
            ExecutorService pool = Executors.newFixedThreadPool(taskSize);
            // 创建多个有返回值的任务
            List<Future> list = new ArrayList<>();
            for (int i = 0; i < taskSize; ++i) {
                Callable c = new MyCallable(i + " ");
                // 执行任务并获取Future对象
                Future f = pool.submit(c);
                list.add(f);
            }
            // 关闭线程池
            pool.shutdown();
    
            // 获取所有并发任务的运行结果
            for (Future f : list) {
                // 从Future对象上获取任务的返回值
                System.out.println(">>>" + f.get().toString());
            }
        }
    }
    
    class MyCallable implements Callable<String> {
        private String taskNum;
    
        MyCallable(String taskNum) {
            this.taskNum = taskNum;
        }
    
        @Override
        public String call() throws InterruptedException {
            System.out.println(Thread.currentThread().getName());
            System.out.println(">>>" + taskNum + "任务启动");
            Date dateTmp1 = new Date();
            Thread.sleep(1000);
            Date dateTmp2 = new Date();
            long time = dateTmp2.getTime() - dateTmp1.getTime();
            System.out.println(">>>" + taskNum + "任务终止");
            return taskNum + "任务返回运行结果,当前任务时间【" + time + "毫秒】";
        }
    }
    

    线程池的作用:

    1、降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
    2、提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
    3、提高线程的可管理性。

    线程池:提供了一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁额外开销,提高了响应的速度。
    线程池的体系结构:
    java.util.concurrent.Executor : 负责线程的使用与调度的根接口
    |--ExecutorService 子接口: 线程池的主要接口
    |--ThreadPoolExecutor 线程池的实现类
    |--ScheduledExecutorService 子接口:负责线程的调度
    |--ScheduledThreadPoolExecutor :继承 ThreadPoolExecutor, 实现 ScheduledExecutorService
    工具类 : Executors
    ExecutorService newFixedThreadPool() : 创建固定大小的线程池
    ExecutorService newCachedThreadPool() : 缓存线程池,线程池的数量不固定,可以根据需求自动的更改数量。
    ExecutorService newSingleThreadExecutor() : 创建单个线程池。线程池中只有一个线程
    ScheduledExecutorService newScheduledThreadPool() : 创建固定大小的线程,可以延迟或定时的执行任务。

    参考:http://www.cnblogs.com/dolphin0520/p/3932921.html

  • 相关阅读:
    第二十六篇 -- wifi学习
    第三篇 -- HTML基础
    第二十九篇 -- 学习第五十六天打卡20190826
    第二篇 -- 软件测试基础
    第一篇 -- 计算机基础
    第二十五篇 -- C++宝典中的图书管理系统
    第五篇 -- 记下曾经的好词好句
    linux平台下Tomcat的安装与优化、windows安装tomcat8.5
    转载:让Windows Server 2012r2 IIS8 ASP.NET 支持10万并发请求
    转载:IIS 之 连接数、并发连接数、最大并发工作线程数、队列长度、最大工作进程数
  • 原文地址:https://www.cnblogs.com/xidian2014/p/10462839.html
Copyright © 2020-2023  润新知