首页 > 编程语言 >Java并发 —— 线程并发(一)

Java并发 —— 线程并发(一)

时间:2024-12-09 21:33:53浏览次数:4  
标签:Runnable Java Thread 并发 线程 ThreadTest 进程 public

线程和进程

进程就是一个内存中运行的应用程序

线程是当前进程中的一个执行任务(控制单元),负责当前进程中程序的执行

区别与联系

  • 根本区别:进程是操作系统资源分配的基本单位,线程是处理器任务调度和执行的基本单位

  • 包含关系:一个进程可以有多个线程,至少有一个

  • 内存分配:同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的

  • 影响关系:一个进程崩溃后,在保护模式下,不会对其他进程产生影响,而一个线程崩溃后,整个进程都会死掉,所以多进程比多线程健壮

  • 执行过程:每个进程都有独立的程序运行入口、顺序执行序列和程序出口,而线程不能独立执行,必须依存在应用程序中

多线程

创建多线程方式

  1. 继承Thread
     通过继承 Thread 类,重写其run()方法,run()方法中定义了线程执行的具体任务,创建该类的实例后,调用其start()方法来启动线程

    Thread 本质上是实现了 Runnable 接口的一个实例,代表线程的一个实例。

    public class ThreadTest extends Thread{
        @Override
        public void run() {
            System.out.println("ThreadTest");
        }
    }
    
    public class Main {
      public static void main(String[] args) {
          ThreadTest threadTest = new ThreadTest();
          threadTest.start();
        }
    }
    
  2. 实现Runnable接口
     实现 Runnable 接口后,通过重写其run()方法,然后将此 Runnable 对象作为参数传递给 Thread 类的构造器,创建 Thread 对象后,调用其 start()方法启动线程

    如果自己的类已经继承了一个类,由于Java是单继承的,所以没法用第一种方式,就可以通过实现 Runnable 接口创建多线程,在 Runnable 接口中只有一个 run()方法

    public class ThreadTest implements Runnable{
        @Override
        public void run() {
            System.out.println("Runnable");
        }
    }
    public class Main {
        public static void main(String[] args) {
            Thread thread = new Thread(new ThreadTest());
            thread.start();
        }
    }
    
  3. 基于线程池的方式(Executor框架)
     这是种更高效的线程管理方式,避免了频繁创建和销毁线程的开销,可以通过 Executor 类的静态方法创建不同类型的线程池

    public class ThreadTest implements Runnable{
        @Override
        public void run() {
            System.out.println("Executor");
        }
    }
    public class Main {
        public static void main(String[] args) {
    //        创建固定大小的线程池
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            for (int i = 0; i < 10; i++) {
    //            提交任务到线程池执行
                executorService.submit(new ThreadTest());
            }
    //        关闭线程池
            executorService.shutdown();
        }
    }
    

三种方式的优缺点

继承Thread

  • 优点:编写简单,如果要访问当前线程,无需使用Thread.currentThread()方法,直接使用this即可

  • 缺点:Java的单继承,在继承了Thread类后,不能再继承其他类了,有局限性

实现Runnable接口

  • 优点:在实现了接口后,仍然可以继承其他类。在这种情况下,可以多个线程共享同一个目标对象,所以非常适合多个相同线程处理同一份资源的情况,从而将CPU代码和数据分开,形成清晰的模型

  • 缺点:编程较为复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法

线程池(Executor框架)

  • 优点:线程池可以重用预先创建的线程,避免了线程创建和销毁的开销,提高程序的性能,对于快速响应的并发请求,线程池可以迅速提供线程来处理任务,减少等待时间。并且线程池可以有效控制运行的线程数量,防止创建过多的线程导致系统资源被耗尽(内存溢出),节约系统资源,可以最大化CPU利用率和系统吞吐率

  • 缺点:增加了程序复杂度,特别是涉及到线程池参数调整和故障排查时,错误的配置可能导致资源耗尽、死锁等问题

四种线程池

Java中线程池的顶级接口是Executor但严格意义上,Executor并不是一个线程池,它只是一个执行线程的工具,真正的线程池接口是ExecutorService

  • newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

  • newFixedThreadPool: 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

  • newScheduledThreadPool:创建一个可定期或者延时执行任务的定长线程池,支持定时及周期性任务执行。

  • newSingleThreadExecutor:返回一个线程池(单一线程),在其他线程死后(或发生异常时),重新启动一个线程代替原来的线程执行下去

标签:Runnable,Java,Thread,并发,线程,ThreadTest,进程,public
From: https://www.cnblogs.com/codyxz/p/18596072

相关文章

  • java批量修改hive_sql文件
    java批量修改hive_sql文件场景:需要批量迁移sql代码,有几百个sql文件按需要处理,一个个处理的非常费时费力修改要求:1:注释删除分区脚本--ALTERTABLEtest_db.clauseDROPpartition(pt_day='${hivevar:runDate}');2:新增清空表脚本truncatetabletest_db.claus......
  • JavaSwing JTree
    packagecom.java.view;importjava.awt.Color;importjava.awt.Cursor;importjava.awt.Dimension;importjava.awt.FlowLayout;importjava.awt.Font;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.awt.event.ItemEvent;......
  • C#和Java异同点
    C#C#(读作“CSharp”),C#是面向对象的、面向组件的编程语言。C#是由C和C++衍生出来的一种安全的、稳定的、简单的、优雅的面向对象编程语言。它在继承C和C++强大功能的同时去掉了一些它们的复杂特性(例如,没有宏以及不允许多重继承)。C#综合了VB简单的可视化操作和C++的高运行效率......
  • Java Web 开发学习中:过滤器与 Ajax 异步请求
    一、过滤器Filter:过滤器的概念与用途在一个庞大的Web应用中,有许多资源需要受到保护或进行特定的预处理。过滤器就像是一位智能的守卫,站在资源的入口处,根据预先设定的规则,决定哪些请求可以顺利访问资源,哪些请求需要被拦截或进行特殊处理。比如,在众多页面中,判断用户是否登录......
  • JavaScript学习
    关于jsJavaScript是一种动态的、弱类型的解释型语言,最初设计用于浏览器端的交互。特点轻量级:语法简单,入门门槛低。跨平台:支持在浏览器、Node.js等多种环境中运行。解释型:无需编译,直接在运行时执行。事件驱动:非常适合处理异步任务,如用户交互、网络请求等。核心概念变......
  • 【JavaScript编程】JavaScript中Error与Exception
    在JavaScript的编程宇宙中,错误处理是构筑稳健程序大厦的基石,而精准把握错误(Error)与异常(Exception)的差异,则是编写高质量、可维护代码的关键。一、Error:预见性与精确处理的艺术本质与特点错误(Error)通常代表着那些在代码执行流程中可以被提前预见,并需要开发者进行精确且手动处理......
  • java基础Day1 markdown
    Markdown标题##二级标题字体粗体:**Hello,World!**斜体:*Hello,World!*斜体+粗体:***Hello,World!***划线:~~Hello,World!~~引用一二三>引用内容分割线***or---图片![截图]()超链接点击跳转到博客园[点击跳转](链接)列表ABCA减号空......
  • JS-5 JavaScript注释与常见输出方式
    注释与输出方式:注释:单行注释、多行注释。输出方式:弹出框、页面输出、控制台输出。 1、JavaScript注释源码中注释是不被引擎所解释的,它的作用是对代码进行解释。 JavaScript提供两种注释的写法:一种是单行注释,用//起头;另一种是多行注释,放在/和/之间。//这是......
  • 2025计算机毕设选题推荐【Java方向】【带创新点】
    ✅博主介绍:CSDN毕设辅导博主、Java领域优质创作者✅技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、>Python、爬虫、数据可视化、小程序、安卓app、大数据、机器学习等设计与开发。✅主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码......
  • Java 配置文件读取指南:多种方式解析与应用
    目录引言使用ResourceBundle读取配置文件使用Properties读取配置文件并创建DataSource3.1从文件系统读取配置文件3.2从类路径读取配置文件使用ConfigurableApplicationContext读取Spring配置文件使用YamlPropertiesFactoryBean读取YAML配置文件使用Hi......