首页 > 其他分享 >多线程基础

多线程基础

时间:2024-10-26 09:16:19浏览次数:8  
标签:状态 Thread 基础 线程 进程 new 多线程 public

一、线程、程序、进程的定义及区别

程序:一组计算机能识别和执行的指令、它是一些保存在磁盘上的指令的有序集合。 进程:程序的一次执行过程, 是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。 线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。 进程与线程区别:
  • 线程与进程不同的是同类的多个线程共享进程的方法区资源,但每个线程有自己的程序计数器虚拟机栈本地方法栈,所以系统在产生一个线程
  • 在各个线程之间做切换工作时,负担要比进程小得多

二、实现多线程的方法

实现线程的方法有很多种

  • ①继承Thread类;

  • ②实现Runnable接口;

  • ③实现Callable接口;

  • ④使用ExecutorService线程池;

  • ⑤使用CompletableFuture类;

  • ⑥基于ThreadGroup线程组;

  • ⑦使用FutureTask类;

  • ⑧使用匿名内部类或Lambda表达式;

  • ⑨使用Timer定时器类;

  • ⑩使用ForkJoin线程池或Stream并行流。

在这里简单列举四种: 

  1. 继承Thread类:
  2. 这是最普通的方式,通过 继承Thread类,重写run方法,来实现多线程。

  3. public class ExtendsThread extends Thread { @Override public void run() { System.out.println("1......"); } public static void main(String[] args) { new ExtendsThread().start(); } }
  4. 实现Runnable接口

    public class ImplementsRunnable implements Runnable {
        @Override
        public void run() {
            System.out.println("2......");
        }
    
        public static void main(String[] args) {
            ImplementsRunnable runnable = new ImplementsRunnable();
            new Thread(runnable).start();
        }
    }

    这也是一种常见的方式,通过实现Runnable接口并重写run方法来实现多线程。

  5. 实现Callable接口

    public class ImplementsCallable implements Callable<String> {
        @Override
        public String call() throws Exception {
            System.out.println("3......");
            return "zhuZi";
        }
    
        public static void main(String[] args) throws Exception {
            ImplementsCallable callable = new ImplementsCallable();
            FutureTask<String> futureTask = new FutureTask<>(callable);
            new Thread(futureTask).start();
            System.out.println(futureTask.get());
        }
    }

    和上一种方式类似,只不过这种方式可以拿到线程执行完的返回值。

  6. 使用ExecutorService线程池

    public class UseExecutorService {
        public static void main(String[] args) {
            ExecutorService poolA = Executors.newFixedThreadPool(2);
            poolA.execute(()->{
                System.out.println("4A......");
            });
            poolA.shutdown();
    
            // 又或者自定义线程池
            ThreadPoolExecutor poolB = new ThreadPoolExecutor(2, 3, 0,
                    TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(3),
                    Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
            poolB.submit(()->{
                System.out.println("4B......");
            });
            poolB.shutdown();
        }
    }

    这种属于进阶方式,可以通过Executors创建线程池,也可以自定义线程池。

三、线程生命周期和状态

Java 线程在运行的生命周期中的指定时刻只可能处于下面 6 种不同状态的其中一个状态:

  • NEW: 初始状态,线程被创建出来但没有被调用 start()
  • RUNNABLE: 运行状态,线程被调用了 start()等待运行的状态。
  • BLOCKED:阻塞状态,需要等待锁释放。
  • WAITING:等待状态,表示该线程需要等待其他线程做出一些特定动作(通知或中断)。
  • TIME_WAITING:超时等待状态,可以在指定的时间后自行返回而不是像 WAITING 那样一直等待。
  • TERMINATED:终止状态,表示该线程已经运行完毕。

线程在生命周期中并不是固定处于某一个状态而是随着代码的执行在不同状态之间切换。

 Java 线程状态变迁图

 由上图可以看出:线程创建之后它将处于 NEW(新建) 状态,调用 start() 方法后开始运行,线程这时候处于 READY(可运行) 状态。可运行状态的线程获得了 CPU 时间片(timeslice)后就处于 RUNNING(运行) 状态。

  • 当线程执行 wait()方法之后,线程进入 WAITING(等待) 状态。进入等待状态的线程需要依靠其他线程的通知才能够返回到运行状态。
  • TIMED_WAITING(超时等待) 状态相当于在等待状态的基础上增加了超时限制,比如通过 sleep(long millis)方法或 wait(long millis)方法可以将线程置于 TIMED_WAITING 状态。当超时时间结束后,线程将会返回到 RUNNABLE 状态。
  • 当线程进入 synchronized 方法/块或者调用 wait 后(被 notify)重新进入 synchronized 方法/块,但是锁被其它线程占有,这个时候线程就会进入 BLOCKED(阻塞) 状态。
  • 线程在执行完了 run()方法之后将会进入到 TERMINATED(终止) 状态。

标签:状态,Thread,基础,线程,进程,new,多线程,public
From: https://blog.csdn.net/2301_79814793/article/details/143247956

相关文章

  • 【Web前端】JavaScript 对象基础
     JavaScript是一种以对象为基础的编程语言,操作数据时,实际都是在处理对象。可以使用简单的数据类型(如字符串、数字和布尔值)来实现一些功能,但深入了解JavaScript对象的运作,将使你能够编写更强大和灵活的代码。对象基础JavaScript中,对象是由一组键(或属性)和值组成的无......
  • Redis基础知识(学习笔记1--五种基础数据结构)
    Redis,Remote Dictionary Server,远程字典服务。Redis的性能极高:其读的速度可以达到11W/s,写的速度可以到达8W/s。高性能的原因(1)操作在内存中发生;(2)C语言开发;(3)源码简单精细(集性能与优雅于一身),早期版本源码只有2W行左右,从3.0版本(开始支持cluster),代码变成了5W左右。Redis有5种......
  • Cocos Creator引擎开发:Cocos Creator基础入门_CocosCreator实战项目案例
    CocosCreator实战项目案例在本节中,我们将通过一个具体的动作游戏项目案例,来深入理解CocosCreator引擎的开发流程和核心功能。这个项目将帮助你掌握从项目创建到发布的一系列步骤,包括场景设计、角色控制、动画制作、碰撞检测、UI设计等。项目概述我们将开发一个简单的2......
  • Cocos Creator引擎开发:Cocos Creator基础入门_CocosCreator网络编程
    CocosCreator网络编程在网络编程中,CocosCreator提供了多种方式来实现客户端与服务器之间的通信。网络编程在游戏开发中至关重要,尤其是在多人游戏、在线对战或需要从服务器获取数据的游戏中。本节将详细介绍如何在CocosCreator中实现基本的网络通信功能,包括使用WebSo......
  • Cocos Creator引擎开发:Cocos Creator基础入门_CocosCreator性能优化
    CocosCreator性能优化1.渲染优化1.1减少DrawCall在CocosCreator中,DrawCall是影响渲染性能的一个重要因素。每个DrawCall都会导致GPU和CPU之间的数据传输,因此减少DrawCall的数量可以显著提高游戏的渲染性能。原理DrawCall是指从CPU向GPU发送渲染指令的过程。每......
  • 实验2 类和对象_基础编程1
    1.实验任务1t.h源代码:1#pragmaonce2#include<string>34//类T:声明5classT{6public:7//对象属性、方法8T(intx=0,inty=0);//普通构造函数9T(constT&t);//复制构造函数10T(T&&t);......
  • Redis 安装部署与基础学习
    Redis安装部署与学习一、简介Redis(RemoteDictionaryServer)是一个开源的内存数据库,遵守BSD协议,它提供了一个高性能的键值(key-value)存储系统,常用于缓存、消息队列、会话存储等应用场景。也就是说redis数据库与我们之前学的MySQL,ClickHouse都不一样,是一个非关系型数据库。总......
  • AGI大模型学习路线,从零基础到就业,神仙级教程你学会了吗?
    大模型学习路线建议先从主流的Llama开始,然后选用中文的Qwen/Baichuan/ChatGLM,先快速上手体验prompt工程,然后再学习其架构,跑微调脚本如果要深入学习,建议再按以下步骤,从更基础的GPT和BERT学起,因为底层是相通的,而且实际落地到一个系统中,应该也是大模型结合小模型(大模型在做判......
  • 书生大模型实战营第4期系列课程——1.1 InternStudio开发机和Linux基础
    书生大模型(InternLM2.5)是由上海人工智能实验室推出的书生·浦语系列模型的全新版本。相较于上一代,InternLM2.5全面增强了在复杂场景下的推理能力,支持1M超长上下文,能自主进行互联网搜索并从上百个网页中完成信息整合。开源链接:https://github.com/InternLM/InternLM书生大......
  • python编程基础
    @目录1.python中的变量和数据类型1.1变量1.2python基本数据类型1.3基本输入与输出输入(Input)输出(Output)基本输出打印多个参数格式化输出打印到文件1.4python中的运算符算术运算符比较运算符赋值运算符逻辑运算符位运算符成员运算符身份运算符2.python中的列表、元组、字典、集合2.1......