Java 基础之多线程

Java 多线程编程:从基础到实战! 多线程编程是 Java 中的一个核心概念,它允许多个线程同时执行任务,从而提高程序的效率和响应性。在现代应用程序中,多线程编程无处不在,尤其是在处理高并发任务时。今天,我们将从基础到实战深入讲解 Java 的多线程编程,帮助你更好地理解和应用它。 阅读详情



一、什么是线程?它与进程有什么区别?为什么要使用多线程?


      线程是指程序在执行过程中,能够执行程序代码的一个执行单元。在 Java 语言中线程有 4 种运行状态:运行、就绪、挂起和结束。

       进程是指一段正在执行的程序。而线程有时也被称为轻量级的进程,各个线程之间共享程序的内存空间(代码段、数据段和堆空间)及一些进程级的资源(例如打开文件),但是各个线程拥有自己的栈空间

      在操作系统级别上,程序的执行都是以进程为单位的,而每个进程中通常都会有多个线程互不影响地并发执行,那么为什么要使用多线程?其实,多线程的使用为程序的研发带来了巨大的便利,具体而言有以下几个方面的内容:

1)使用多线程可以减少程序的响应时间,在单线程的情况下,如果某个操作很耗时,或者陷入长时间的等待(如等待网络响应),此时程序将不会响应鼠标、键盘等操作,使用多线程后,可以把这个耗时的线程分配到一个单独的线程中去执行,从而使的程序具备了更多的交互性

2)与进程相比,线程的创建和切换开销更小,由于启动一个新的线程必须给这个线程分配独立的地址空间,建立许多数据结构来维护线程代码段,数据段等信息,而运行于同一进程内的线程共享代码段和数据段,线程的启动,切换的开销比进程要少很多,同时多线程在数据共享方面效率非常高

3)多 CPU 或者多核计算机本身就具有执行多线程的能力,如果使用单个线程,将无法重复利用计算机资源,造成资源的浪费,因此在多 CPU 计算机上使用多线程能提高 CPU 的利用率

4)使用多线程能简化程序的结构,是程序便于理解和维护,一个非常复杂的进程可以分成多个线程来执行


二、同步和异步有什么区别?


      在多线程的环境中,经常会碰到数据的共享问题,即当多个线程需要访问同一个资源时,它们需要以某种顺序来确保该资源在某一时刻只能被一个线程使用,否则,程序的运行结果将是不可预测的,在这种情况下就必须对数据进行同步,例如多个线程同时对同一数据进行写操作,即当线程 A 需要使用某个资源时,如果这个资源正在被线程 B 使用,同步机制就会让线程 A 一直等待下去,直到线程 B 结束对该资源的使用后,线程 A 才能使用这个资源,由此可见,同步机制可以保证资源的安全

      想要实现同步操作,必须要获得每一个线程的对象锁,获得它可以保证在同一时刻只有一个线程可以进入临界区(访问互斥资源的代码块),并且在这个锁被释放之前,其他的线程就不能再进入这个临界区,如果还有其它线程想要获得该对象的锁,只能进入等待队列等待,只有当拥有该对象锁的线程退出该临界区域时,锁才会被释放,等待队列中优先级最高的线程才能获得该锁,从而进入共享代码区

      Java 语言在同步机制中提供了语言级的支持,可以通过使用 synchronized 关键字来实现同步,但该方法并非万金油,它是以很大的系统开销为代价的,有时候可能造成死锁,所以同步控制并非越多越好,要尽量避免无谓的同步机制,实现同步的方式有两种:一种是利用同步代码块来实现,而另一种是利用同步方法来实现

      异步与非阻塞类似,由于每个线程都包含了运行时所需要的数据或方法,因此,在进行输入输出处理时,不必关心其它线程的状态和行为,也不必等到输入输出处理完毕才返回,当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,异步能够提高程序的效率


三、如何实现 Java 的多线程


Java 虚拟机允许应用程序并发的运行多个线程,在 Java 语言中,多线程的实现一般有以下 3 种方法,其中前两种为常用方法

1)继承 Thread 类,重写 run() 方法

     Thread 本质上也是实现了 Runnable 接口的一个实例,它代表了一个线程的实例,并且启动线程的唯一方法,就是通过 Thread 类的 start() 的方法,start() 方法是一个 native (本地)方法,它将启动一个新线程,并执行 run 方法,(Thread 中提供的 run() 方法是一个方法),这种方式通过自定义直接 extend Thread,并重写 run() 方法,就可以启动新线程并执行自己定义的额 run() 方法,需要注意的是,调用 start() 方法后并不是立即执行多线程代码,而是使得该线程变为可运行状态(Runnable),什么时候运行多线程代码是由操作系统决定的

/** 
 * 继承 Thread 创建子线程 
 */  
class MyThread extends Thread {  
    @Override  
    public void run() {  
        //处理具体的逻辑  
    }  
}

那么如何启动这个线程呢?只需要 new 出 MyThread 的实例,然后调用它的 start() 方法,这样 run() 方法中的代码就会运行在子线程,如下:new MyThread().start();

2)实现 Runnable 接口,并实现该接口的 run() 方法

/** 
 * 实现 Runnable 接口创建子线程 
 */  
class MyThread implements Runnable {  
    @Override  
    public void run() {  
        //处理具体的逻辑  
    }  
}

如果使用这种写法,启动线程的方法也需要相应的改变,如下:

MyThread myThread = new MyThread();  
new Thread(myThread).start();

      Thread 构造函数接受一个 Runnable 参数,我们 new 出的 MyThread 正是一个实现了 Runnable 接口的对象,所以可以直接将它传入到 Thread 的构造函数里,接着就和上面的一样了,调用 Thread 的 start() 方法,run() 方法中的代码就会在子线程当中运行了

      其实,不管是通过继承 Thread 类还是通过使用 Runnable 接口来实现多线成的方法,最终还是通过 Thread 的对象的 API 来控制线程的

3)实现 Callable 接口,重写  call 方法

      Callable 接口实际是属于 Executor 框架中的功能类,Callable 接口与 Runnable 接口的功能类似,但提供了比 Runnable 更强大的功能,主要表现为以下 3 点:

  • Callable 可以在任务结束后提供一个返回值,Runnable 无法提供这个功能
  • Callable 中的 call 方法可以抛出异常,而 Runnable 的 run 方法不能抛出异常
  • 运行 Callable 可以拿到一个 Future 对象,Future 对象表示异步计算的结果,它提供了检查计算是否完成的方法,由于线程属于异步计算模型,因此无法从别的线程中得到函数的返回值,在这种情况下,就可以使用 Future 来监视目标线程调用 call() 方法的情况,当调用 Future 的 get() 方法以获取结果时,当前线程就会阻塞以,直到 call() 方法结束返回结果
public class CallableAndFuture {
    /**
     * 创建线程类
     */
    public static class CallableTest implements Callable<String> {

        @Override
        public String call() throws Exception {
            return "Helle World";
        }
    }

    public static void main(String[] args){
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        //启动线程
        Future<String> future = executorService.submit(new CallableTest());
        //等待多线程结束,并获取返回结果
        try {
            System.out.println("waiting thread to finish");
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

      以上代码只供参考,以上 3 种方式中,前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的,当需要实现多线程时,一般推荐实现 Runnable 接口的方式,其原因是:

      首先,Thread 类定义了多种方法可以被派生类使用或重写,但是只有 run() 方法是必须被重写的,在 run() 方法中实现这个线程的主要功能,这当然是实现 Runnable 接口所需的方法

     其次,很多 Java 开发人员认为,一个类仅在需要被加强或修改时,才会被继承,因此如果没有必要重写 Thread 类中的其它方法,那么继承 Thread 的实现方式与实现 Runnable 接口的效果相同,在这种情况下最好通过实现 Runnable 接口的方式来创建线程

引申:一个类是否可以同时继承 Thread 与实现 Runnable 接口?

首先说明是可以的,为了说明这个问题,给出如下示例:

public class Test extends Thread implements Runnable {

    public static void main(String args[]) {
        Thread thread = new Thread(new Test());
        thread.start();
    }
}

      从上例中可以看出,Test 类实现了 Runnable 接口,但是并没有实现接口的 run() 方法,可能有些读者会认为这导致编译错误,但实际它是能够编译运行的,因为 Test 类从 Thread 类中继承了 run 方法,这个继承的 run() 方法可以被当做对 Runnable 接口的实现,因此这段代码能够编译通过,当然也可以不使用继承的 run() 方法,而是需要通过在 Test 类中重写 run() 方法来实现   Runnable 接口中的  run() 方法,示例如下:

public class Test extends Thread implements Runnable {

    @Override
    public void run() {
        System.out.println("this is run");
    }

    public static void main(String args[]) {
        Thread thread = new Thread(new Test());
        thread.start();
    }
}


四、run() 方法与 start() 方法有什么区别?


     通常,系统通过调用线程类的 start() 方法启动一个线程,此时该线程处于就绪状态,而非运行状态,也就意味着这个线程可以被 JVM 来调度执行,在调度过程中,JVM 通过调用线程类的 run() 方法来完成实际的操作,当 run() 方法结束后,线程就会终止

      如果直接调用线程类的 run() 方法,这会被当作一个普通的函数,程序中仍然只有主线程这一个线程,也就是说 start() 方法能够异步的调用 run() 方法,但是直接调用 run() 方法却是同步的,因此也就无法达到多线程的目的,由此可见,只有通过调用线程类的 start() 方法才能达到多线程的目的


五、多线程同步实现的方法有哪些?


(1)synchronized 关键字

      在 Java 语言中,每个对象都有一个对象锁与之相关联,该锁表明对象在任何时候只容许被一个对象所拥有,当一个线程调用对象的一段 synchronized 代码时,需要先获取这个锁,然后去执行相应的代码,执行结束后释放锁

synchronized 关键字主要有两种用法(synchronized 方法和 synchronized 块),此外该关键字还可以作用于静态方法,或某个实例,但这都对程序的效率有一定的影响

  • synchronized 方法:在方法的声明前加入 synchronized 关键字,示例如下
public synchronized void Test(){}

       只要把多个线程对类需要被同步的资源的操作放到 Test() 方法中,就能保证这个方法在同一时刻只能被一个线程访问,从而保证了多线程访问的安全,然而当一个线程的方法体规模非常大时,把该方法声明为 synchronized 会大大影响程序的执行效率,为了提高程序的效率,Java 提供了 synchronized 块

  • synchronized 块:synchronized 块既可以把任意的代码段声明为 synchronized,也可以指定上锁的对象,有非常高的灵活性,其用法如下:
    synchronized (syncObject){
        //访问syncObject的代码
    }

(2)wait() 方法与 notify() 方法

      当使用某个 synchronized 来修饰某个共享资源时,如果线程 A1 在执行 synchronized 代码,另外一个线程 A2 也将要同时执行同一对象的同一个 synchronized 代码时,线程 A2 将要等到线程 A1 执行完成后,才能继续执行,在这种情况下可以使用 notify() 方法和 wait() 方法

      在 synchronized 代码被执行期间,线程可以调用对象的 wait() 方法,释放对象锁,进入等待状态,并且可以调用 notify() 方法或 notifyAll() 方法通知正在等待的其他线程,notify() 方法仅唤醒一个线程(等待队列中的第一个线程),并容许它去获得锁,notifyAll() 方法唤醒所有等待这个对象的线程,并允许他们去获得锁(并不是让所有唤醒线程都获得锁,而是让他们去竞争)。

(3)Lock

lock(): 以阻塞方式获取锁,也就是说如果获取到了锁,立即返回,如果别的线程持有锁,当前线程等待,直到获取锁后返回

tryLock(): 以非阻塞方式获取锁,只是尝试性的去获取一下锁,如果获取到锁,立即返回 true,否则返回 false


六、sleep() 方法与 wait() 方法有什么区别?


      sleep() 方法与 wait() 方法都是使线程暂停执行一段时间的方法,具体而言,sleep() 方法与 wait() 方法的区别主要表现在如下几个方面:

1)原理不同

      sleep() 方法是 Thread 类的静态方法,是线程用来控制自身流程的,它会使此线程暂停执行一段时间,而把执行机会让给其他线程,等到计时时间一到,次线程会自动苏醒,而 wait() 方法是 Object 类的方法,用于线程间的通信,这个方法会使当前拥有该对象锁的进程等待,直到其他线程调用 notify() 方法(或 notifyAll() 方法)时才醒来,不过开发人员也可以给他指定一个时间,自动醒来

2)对象锁处理机制不同

      由于 sleep() 方法的主要作用是让线程暂停执行一段时间,时间一到则自动恢复,不涉及线程间的通信,因此调用 sleep() 方法并不会释放锁,而 wait() 方法则不同,当调用 wait() 方法后,线程会释放掉它所占用的锁,从而使线程所在对象中的其他synchronized 数据可被别的线程使用

3)使用区域不同

      由于 wait() 方法的特殊意义,因此它必须放在同步控制方法或者同步语句块中使用,而 sleep() 方法可以在任何地方使用

最后由于 sleep() 方法不会释放锁标志,容易导致死锁问题的发生,因此一般情况下不推荐使用,而推荐使用 wait() 方法


七、终止线程的方法有哪些?


       在 Java 语言中,可以使用 stop() 方法与 suspend() 方法来终止线程的执行,当用 Thread.stop() 来终止线程时,它会释放已经锁定的所有监视资源,调用 suspend() 方法容易发生死锁(死锁指的是两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,如果无外力作用,它们都将无法推进),由于调用 suspend() 方法不会释放锁,这就会导致一个问题:如果用一个 suspend 挂起一个有锁的线程,那么在锁恢复之前将不会被释放,如果调用 suspend() 方法,线程将试图取得相同的锁,程序就会发生死锁


八、什么是守护线程?


       Java 提供了两种线程:守护线程与用户线程,守护线程又被称为“服务进程”或“后台线程”是指在程序运行时,在后台提供一种通用服务的线程,这种线程并不属于程序中不可或缺的部分,通俗点将,任何一个守护线程都是整个 JVM 中所有非守护线程的“保姆”

     用户线程和守护线程几乎一样,唯一的不同之处就在于如果用户线程已经全部退出运行,只剩下守护线程存在,JVM 也就退出了,因为当所有非守护程序结束时,没有了被守护者,守护线程也就没有工作可做了,也就没有运行程序的必要,程序也就终止了,同时会杀死所有守护线程





别再傻傻分不清:PX4、Pixhawk、ArduPilot、APM到底啥关系?一张图给你讲明白 本文全面解析开源飞控领域核心概念,厘清PX4、Pixhawk、ArduPilot与APM的定位与关系。通过硬件平台演进史和飞行控制软件对比,帮助开发者理解开源飞控生态,并提供新项目开发建议与特殊需求考量,助力无人机开发中的明智选择。 阅读详情

相关推荐

从MRF8P9040N数据手册到ADS仿真:手把手教你搞定LDMOS功放设计(附完整模型下载)

本文详细解析了MRF8P9040N LDMOS功率放大器的数据手册关键参数,并提供了在ADS中进行仿真的完整指南。从模型导入、直流工作点验证到负载牵引与阻抗匹配设计,逐步指导工程师完成高效功放设计。文章还包含调试技巧和常见问题解决方案,帮助优化射频功放性能。

weixin_27015733的博客 490

2019年华为JAVA面试题系列

面试发现经常有些重复的面试问题,自己也应该学会记录下来,最好自己能做成笔记,在下一次面的时候说得有条不紊,深入具体,面试官想必也很开心。以下是我个人总结,请参考: HashSet底层原理:(问了大几率跟HashMap一起面) HashMap底层原理:(非常大几率问到) Hashtable底层原理:(问的少,问了大几率问你跟HashMap的区别) synchronized底层如何实现?锁优化...

zhuzj12345的博客 1367

ST7789驱动实战:从SPI时序到RGB565显示的完整配置解析

本文详细解析了ST7789液晶驱动芯片的SPI时序配置与RGB565显示实现,从数据手册解读到代码实战,涵盖SPI接口配置、关键寄存器设置及完整初始化流程。通过优化DMA传输和常见问题排查,帮助开发者高效驱动ST7789显示屏,适用于嵌入式显示项目开发。

weixin_29162439的博客 184

Java学习笔记-《Java程序员面试宝典》-第四章基础知识-4.10多线程(4.10.5-4.10.10)

4.10.5 多线程的实现方法有哪些 当使用多线程访问一个资源时,非常容易出现线程安全的问题(例如,当多个线程同时对一个数据进行修改时,会导致某些线程对数据的修改丢失)。因此需要采用同步机制来解决这种问题。Java主要提供了3种实现同步机制的方法: 1>synchronized关键字 在Java语言中,每个对象都有一个对象锁与之相关联,该锁表明对象在任何时候只允许被一个线程所拥有,当一个线程

qq_28814687的博客 529

Emuelec系统安装全流程:超详细版指南(从零开始)

手把手带你完成emuelec系统的完整安装,从基础准备到系统配置一步不落,适合新手入门。深入解析emuelec在各类设备上的部署技巧,让复古游戏体验更流畅。

weixin_42594419的博客 1972

CentOS 7/8 系统下,基于Docker Compose一键部署Dify AI应用平台

本文详细介绍了在CentOS 7/8系统下,使用Docker Compose一键部署Dify AI应用平台的完整流程。从系统环境准备、Docker引擎安装与加速配置,到获取Dify项目、关键环境变量设置,再到服务启动、状态监控及初始化访问,提供了手把手的部署指南和常见问题排查方法,帮助用户快速搭建稳定、可维护的AI应用开发环境。

q5r6s7的博客 139

操作系统原理及应用复习(第2版)大部分课后习题

操作系统原理及应用复习 第一章操作系统概论 1.1 什么是操作系统,有哪些基本功能和特点? 操作系统是覆盖在裸机上的第一层软件,他直接控制,管理各种资源。 基本功能: 提供人机接口 命令级接口 程序级接口 图形界面 管理计算机资源 处理机管理 存储管理 设备管理 文件管理 基本特点:并发、异步、共享和虚拟。 1.3 操作系统的结构有哪几种类型?各有什么特点?Linux系统是什么结构? 单道批处理系统 在当时被称为监督程序,是操作系统的雏形 联机批处理 脱机批处理 多道批处理系统

Yg123345的博客 5675

Python与PyCharm安装配置教程:从零搭建开发环境

编程入门的第一步是搭建开发环境,而Python解释器与IDE工具的选择常让新手困惑。Python作为解释型语言,负责将代码翻译为机器指令,而PyCharm作为集成开发环境,提供代码编辑、调试与项目管理功能,两者协同工作构成高效开发基础。环境变量PATH的配置是安装过程中的关键环节,正确处理可避免“python不是内部或外部命令”的常见错误。理解pip包管理机制,则能轻松安装第三方库并管理项目依赖。从下载官方安装包到运行第一个Hello World程序,再到利用虚拟环境隔离应用依赖,这套流程适用于Window

benben 685

JavaSE基础---流程控制

do-while循环结构会先执行循环体,然后再判断布尔表达式的值,若条件为真,执行循。for循环语句是支持迭代的一种通用结构,是最有效、最灵活的循环结构。for循环在执行条件判定后,先执行的循环体部分,再执行步进。if语句对布尔表达式进行一次判定,若判定为真,则执行{}中的语句块,否则跳过该语。在循环刚开始时,会计算一次“布尔表达式”的值,若条件为真,执行循环体。当布尔表达式为真时,执行语句块1,否则,执行语句块2。continue 语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语。

weixin_64768917的博客 320

智能车小白也能懂:手把手教你用LM358和工字电感搭建电磁循迹模块(附PCB设计避坑)

本文详细介绍了如何利用LM358运放和工字电感搭建智能车电磁循迹模块,从电感选型、电路设计到PCB布局和焊接调试,提供全流程实战指南。特别针对新手常见问题,如信号干扰、电路饱和等,给出具体解决方案和参数配置,帮助智能车比赛爱好者快速掌握电磁循迹技术。

weixin_30307921的博客 401

CUDA:实现使用cuSolverSP底层API实现Cholesky因式分解(附完整源码)

CUDA:实现使用cuSolverSP底层API实现Cholesky因式分解(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 346

c语言部分函数使用方法(sleep、system、strcmp、rand、srand、time、memset、strcat、strncat、strstr)

1.sleep()函数: 作用:使程序在进行到这一步时,停顿一段时间再进行下一步。 在括号里输入数字的单位是毫秒。 使用此函数要加上头文件<windows.h>。 2.system(“cls”)函数: 作用:清空屏幕上先前显示的内容。 使用前要加上头文件<stdlib.h> 3.strcmp(字符串1,字符串2)函数: 作用:比较两个字符串是否相等。 使用时要加上头文件<string.h> strcmp比较的是两个字符串对应位置上的...

weixin_63716012的博客 1502

全球建筑物提取数据集(免费下载):微软/GlobalMLBuildingFootprints

这个是GitHub上的开源数据集: https://github.com/microsoft/GlobalMLBuildingFootprints 介绍 必应地图正在世界各地发布开放式建筑足迹。我们从 2014 年到 2021 年间的 Bing Maps 图像中检测到了 7.77 亿座建筑物,包括 Maxar 和 Airbus 的图像。数据可在 ODbL 下免费下载和使用。该数据集补充了我们的其他版本。 包括的地区 执照 此数据由 Microsoft 根据Open Dat..

此星光明博客 6290

JAVA多线程基础

JAVA多线程基础 1.什么是并发原理? 多线程:多线程允许我们“同时”执行多段代码。 线程是并发运行的,线程调度会统一规划CPU时间,将CPU的时间划分为若干片段,然后尽可能的均匀分配给所要并发运行的线程,每个线程在获取CPU时间片段后CPU就会运行它的任务,当时间片段用完后,Cpu会离开并执行获取到CPu时间片的线程,所以,所有线程并非真正的“同时”运行着代码,而是走走停停,这种微观上走走停停,在宏观上感觉是同步进行的现象称为“并发运行”。 2.创建线程Thread 1. 方式一:继承Thread并重写

weixin_47600732的博客 4277

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

『Java多线程』基础之基础

Java基础篇~多线程 线程概念 程序(Program) ​ 程序是指令、数据及其组织形式的描述,也就是存储在磁盘或者其他存储设备中含有指令和数据的文件,是一段静态代码 进程(Process) ​ 进程是受操作系统管理的基本单元,是程序的一次动态执行过程,是系统进行资源分配和调度的基本单位,它对应了从代码加载、执行到执行完毕的整个过程,即进程的创建、运行到消亡的过程。从某种程度上来说,进程是正在运行程序的实例,是一个动态概念 多任务(Multi Task) ​ 在一

像写诗一样优雅地写代码~ 7642

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Java之多线程基础

java多线程基础

zhanghuaiwei 444

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Java多线程基础

Java多线程基础

weixin_44525733的博客 1136

Java 多线程基础

在Java开发中,我们经常会用到多线程来解决一些异步的问题,多线程属于Java的重点与难点,下面我们就一步一步的讲解Java中的多线程。

HappyHeng的博客 734

java多线程基础

java多线程基础1.线程的相关概念2.线程的启动方式 1.线程的相关概念 进程: 进程就是一个程序或者服务运行的过程在操作系统中的体现,即操作系统中一个独立运行的程序或者服务就是一个进程。 多进程: 现在的操作系统都支持同时运行多个程序或者服务,体现在进程上,就是多个进程可以并行的执行,这称之为操作系统支持多进程。 线程: 一个进程的内部还可以划分出多个并行执行的过程,称之为在进程内部存在线程,线程是操作系统能够进行运算调度的最小单位。 多线程: 一个进程可以存在多个线程,并且这些线程可以并行的执行,这

qq_45903614的博客 326

Java学习基础笔记——多线程基础部分

Java多线程基础知识

jiangnank的博客 1160

JAVA多线程基础(详解)

实现Runnable接口比继承Thread类所具有的优势:1):适合多个相同的程序代码的线程去处理同一个资源2):可以避免java中的单继承的限制3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立4):线程池只能放入实现Runable或callable类线程,不能直接放入继承Thread的类线程同步方法是通过锁来实现,每个对象都有且仅有一个锁,这个锁与一个特定的对象关联,线程一旦获取了对象锁,其他访问该对象的线程就无法再访问该对象的其他非同步方法。

欢迎来到空说的博客 1324

【JAVA】多线程基础

1.多线程基础 ⑴什么是多线程 运行中的exe程序就是一个进程,进程中独立的子任务就是线程 ⑵线程和进程的区别 进程是系统进行资源分配的一个独立单位,线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位,一个进程可以包括多个线程 ⑶线程的五大状态 新建 创建线程还没有start 就绪 start但是还没有获取CPU时间片 运行 正在执行 阻塞 比如sleep等...

屎蛋的铲屎官 3940

Java基础之多线程

文章简单介绍了java多线程以及多线程最基本的实现方式

paynezj的博客 973
上一篇: Java 基础之容器
下一篇: Android 性能优化之内存优化
QDJdeveloper
博客等级 码龄11年 108粉丝 49原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值