java多线程及

多线程使用

在java中,多线程得主要实现方式有四种:继承Thread类,实现Runnable接口、实现callable接口通过FutureTask包装器来创建Thread线程,使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,而后两种是带返回值的。除此之外,通过Timer启动定时任务,或者通过像Spring Task和quartz这样的第三方任务调度框架也可以开启多线程任务

继承Thread类创建线程

Thread类本质上也是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程比较简单,通过继承Thread类并复写run()方法,就可以启动新线程并执行自己定义的run()方法

复制代码
public class ThreadDemo extends Thread {
    
    public ThreadDemo(String name) {
        // 设置当前线程的名字
        this.setName(name);
    }
    
    @Override
    public void run() {
        System.out.println("当前运行的线程名为: " + Thread.currentThread().getName());
    }
    
    public static void main(String[] args) throws Exception {
        // 注意这里,要调用start方法才能启动线程,不能调用run方法
        new ThreadDemo("MyThreadOne").start();
        new ThreadDemo("MyThreadTwo").start();
        
    }
    
}

输出结果:

复制代码
当前运行的线程名为: MyThreadOne
当前运行的线程名为: MyThreadTwo
实现Runnable接口创建线程

由于Java是单继承机制,如果自己的类已经继承自另一个类,则无法再直接继承Thread类,此时,可以通过实现Runnable接口来实现多线程。

实现Runnable接口并实现其中的run方法,然后通过构造Thread实例,传入Runnable实现类,然后调用Thread的start方法即可开启一个新线程。

复制代码
public class MyRunnable implements Runnable {
    
    @Override
    public void run() {
        System.out.println("当前运行的线程名为: " + Thread.currentThread().getName());
    }
    
    public static void main(String[] args) throws Exception {
        MyRunnable runnable = new MyRunnable();
        new Thread(runnable, "MyThreadOne").start();
        new Thread(runnable, "MyThreadTwo").start();
        
    }
    
}

输出结果:

复制代码
当前运行的线程名为: MyThreadOne
当前运行的线程名为: MyThreadTwo
线程池使用

线程池本质是池化技术的应用,和连接池类似,创建连接与关闭连接属于耗时操作,创建线程与销毁线程也属于重操作,为了提高效率,先提前创建好一批线程,当有需要使用线程时从线程池取出,用完后放回线程池,这样避免了频繁创建与销毁线程。

核心参数

线程池的核心参数决定了池的类型,进而决定了池的特性。

参数 解释 行为
corePoolSize 核心线程数 池中长期维护的线程数量,不主动回收
maximumPoolSize 最大线程数 最大线程数大于等于核心线程数
keepAliveTime 线程最大空闲时间 非核心线程最大空闲时间,超时回收线程
workQueue 工作队列 工作队列直接决定线程池的类型

Executors类默认创建线程池与参数对应关系。

线程池 corePoolSize maximumPoolSize keepAliveTime workQueue
newCachedThreadPool 0 Integer.MAX_VALUE 60 SynchronousQueue
newSingleThreadExecutor 1 1 0 LinkedBlockingQueue
newFixedThreadPool N N 0 LinkedBlockingQueue
newScheduledThreadPool N Integer.MAX_VALUE 0 DelayedWorkQueue
线程池对比
线程池 特点 适用场景
newCachedThreadPool 超时未使用的线程回自动销毁,有新任务时自动创建 适用于低频、轻量级的任务。回收线程的目的是节约线程长时间空闲而占有的资源。
newSingleThreadExecutor 线程池中有且只有一个线程 顺序执行任务
newFixedThreadPool 线程池中有固定数量的线程,且一直存在 适用于高频的任务,即线程在大多数时间里都处于工作状态。
newScheduledThreadPool 定时线程池 与定时调度相关联

https://segmentfault.com/a/1190000041661118

java线程池最全的面试题(仔细揣摩整理)

相关推荐
C4程序员8 分钟前
北京JAVA基础面试30天打卡14
java·开发语言·面试
黑客影儿36 分钟前
Go特有的安全漏洞及渗透测试利用方法(通俗易懂)
开发语言·后端·安全·web安全·网络安全·golang·系统安全
LGL6030A1 小时前
Java学习历程14——制作一款五子棋游戏(4)
java
你好,我叫C小白1 小时前
C语言 常量,数据类型
c语言·开发语言·数据类型·常量
小红帽2.02 小时前
从ioutil到os:Golang在线客服聊天系统文件读取的迁移实践
服务器·开发语言·golang
qq_589568102 小时前
javaweb开发笔记—— 前端工程化
java·前端
Zafir20243 小时前
Qt实现TabWidget通过addTab函数添加的页,页内控件自适应窗口大小
开发语言·c++·qt·ui
阿巴~阿巴~3 小时前
深入解析C++非类型模板参数
开发语言·c++
码农小灰3 小时前
Kafka消息持久化机制全解析:存储原理与实战场景
java·分布式·kafka
程序员鱼皮4 小时前
太香了!我连夜给项目加上了这套 Java 监控系统
java·前端·程序员