`
hanhg
  • 浏览: 136931 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

多线程编程的基础知识点

阅读更多
多线程编程一直是程序员比较头痛和心虚的地方,因为线程执行顺序的不可预知性和调试时候的困难,让不少人在面对多线程的情况下选择了逃避,采用单线程的方式,其实只要我们对线程有了明确的认识,再加上Java内置的对多线程的天然支持,多线程编程不再是一道难以逾越的鸿沟。

    「一」进程、线程、并发执行

    关于进程、线程、并发执行的概念,我们先来看下面的一段话:

    “一般来说,当运行一个应用程序的时候,就启动了一个进程,当然有些会启动多个进程。启动进程的时候,操作系统会为进程分配资源,其中最主要的资源是内存空间,因为程序是在内存中运行的。

    在进程中,有些程序流程块是可以乱序执行的,并且这个代码块可以同时被多次执行。实际上,这样的代码块就是线程体。线程是进程中乱序执行的代码流程。当多个线程同时运行的时候,这样的执行模式成为并发执行。“

    上面这段话引自51CTO网站“熔岩”的博客一篇文章《Java多线程编程总结》,读者可参考本文获得更详细的知识。

    下面我以一个日常生活中简单的例子来说明进程和线程之间的区别和联系:



    这副图是一个双向多车道的道路图,假如我们把整条道路看成是一个“进程”的话,那么图中由白色虚线分隔开来的各个车道就是进程中的各个“线程”了。

    ①这些线程(车道)共享了进程(道路)的公共资源(土地资源)。

    ②这些线程(车道)必须依赖于进程(道路),也就是说,线程不能脱离于进程而存在(就像离开了道路,车道也就没有意义了)。

    ③这些线程(车道)之间可以并发执行(各个车道你走你的,我走我的),也可以互相同步(某些车道在交通灯亮时禁止继续前行或转弯,必须等待其它车道的车辆通行完毕)。

    ④这些线程(车道)之间依靠代码逻辑(交通灯)来控制运行,一旦代码逻辑控制有误(死锁,多个线程同时竞争唯一资源),那么线程将陷入混乱,无序之中。

    ⑤这些线程(车道)之间谁先运行是未知的,只有在线程刚好被分配到CPU时间片(交通灯变化)的那一刻才能知道

「二」JVM与多线程

    Java编写的程序都运行在在Java虚拟机(JVM)中,在JVM的内部,程序的多任务是通过线程来实现的。

    每用java命令启动一个java应用程序,就会启动一个JVM进程。在同一个JVM进程中,有且只有一个进程,就是它自己。在这个JVM环境中,所有程序代码的运行都是以线程来运行的。JVM找到程序程序的入口点main(),然后运行main()方法,这样就产生了一个线程,这个线程称之为主线程。当main方法结束后,主线程运行完成。JVM进程也随即退出。

    操作系统将进程线程进行管理,轮流(没有固定的顺序)分配每个进程很短的一段时间(不一定是均分),然后在每个进程内部,程序代码自己处理该进程内部线程的时间分配,多个线程之间相互的切换去执行,这个切换时间也是非常短的。

    「三」Java语言对多线程的支持

    Java语言对多线程的支持通过类Thread和接口Runnable来实现。这里就不多说了。这里重点强调两个地方:

// 主线程其它代码段
ThreadClass subThread = new ThreadClass();
subThread.start();
// 主线程其它代码段
subThread.sleep(1000);
    有人认为以下的代码在调用start()方法后,肯定是先启动子线程,然后主线程继续执行。在调用sleep()方法后CPU什么都不做,就在那里等待休眠的时间结束。实际上这种理解是错误的。因为:

    ①start()方法的调用后并不是立即执行多线程代码,而是使得该线程变为可运行态(Runnable),什么时候运行是由操作系统决定的。

    ②Thread.sleep()方法调用目的是不让当前线程独自霸占该进程所获取的CPU资源,以留出一定时间给其他线程执行的机会(也就是靠内部自己协调)。

「四」线程的状态切换

    前面我们提到,由于线程何时执行是未知的,只有在CPU为线程分配到时间片时,线程才能真正执行。在线程执行的过程中,由可能会因为各种各样的原因的原因而暂停(就像前面所举的例子一样:汽车只有在交通灯变绿的时候才能够通行,而且在行驶的过程中可能会出现塞车,等待其它车辆通行或转弯的状况)。

    这样线程就有了“状态”的概念,下面这副图,是从《Java多线程编程总结》一文中摘录出来的。很好的反映了线程在不同情况下的状态变化



    1、新建状态(New):新创建了一个线程对象。

    2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。

    3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。

    4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:

    ①等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。

    ②同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM把该线程放入锁池③其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

    5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

「五」Java中线程的调度API

    Java中关于线程调度的API最主要的有下面几个:

    ①线程睡眠:Thread.sleep(long millis)方法

    ②线程等待:Object类中的wait()方法

    ③线程让步:Thread.yield() 方法

    ④线程加入:join()方法

    ⑤线程唤醒:Object类中的notify()方法

    关于这几个方法的详细应用,可以参考SUN的API,及《Java多线程编程总结》一文第七部分“线程的调度”。这里我重点总结一下这几个方法的区别和使用:

    备注:sleep方法与wait方法的区别:①sleep方法是静态方法,wait方法是非静态方法。

    ②sleep方法在时间到后会自己“醒来”,但wait不能,必须由其它线程通过notify(All)方法让它“醒来”

    ③sleep方法通常用在不需要等待资源情况下的阻塞,像等待线程、数据库连接的情况一般用wait

    备注:sleep/wait与yeld方法的区别:①调用sleep或wait方法后,线程即进入block状态,而调用yeld方法后,线程进入runnable状态

    备注:wait与join方法的区别:①wait方法体现了线程之间的互斥关系,而join方法体现了线程之间的同步关系②wait方法必须由其它线程来解锁,而join方法不需要,只要被等待线程执行完毕,当前线程自动变为就绪③join方法的一个用途就是让子线程在完成业务逻辑执行之前,主线程一直等待直到所有子线程执行完毕。

分享到:
评论

相关推荐

    Linux下C语言多线程编程实例

    Linux 下 C 语言多线程编程实例 Linux 下的多线程编程是一种非常重要的技术,在...本实例提供了一个非常实用的多线程编程示例,帮助我们更好地理解多线程编程的基本概念和技术,并且可以作为实际应用的参考和借鉴。

    JAVA多线程编程技术PDF

    这份“JAVA多线程编程技术PDF”是学习和掌握这一领域的经典资料,涵盖了多线程的全部知识点。 首先,多线程的核心概念包括线程的创建与启动。在Java中,可以通过实现Runnable接口或继承Thread类来创建线程。创建后...

    嵌入式软件开发技术:第5章 嵌入式Linux多线程编程.ppt

    本章节将详细介绍嵌入式Linux多线程编程的基本概念、线程的创建、同步和互斥、线程属性、多线程实验等方面的知识点。 1. 线程基本概念 在Linux系统中,线程是进程内独立的一条运行路线,处理器调度的最小单元,也...

    linux多线程编程.pdf

    本文档主要涉及Linux多线程编程的一些关键知识点,包括pthread线程库的使用、线程的创建、线程的退出以及线程的同步等。 首先,我们来探讨pthread线程库。pthread,全称POSIX threads,是遵循POSIX线程标准的一套...

    sun 多线程编程指南

    本书是关于多线程编程的权威指南,它涵盖了编写高效、安全的多线程程序所需的所有重要知识点。 描述中提到,这是一本“经典多线程文档”,表明了其在行业内的地位和影响力。书中描述了多线程之间的交互和通信机制,...

    Linux多线程编程手册

    Linux多线程编程手册不仅提供了多线程编程的基本操作,还涉及到了高级主题,如线程取消点的创建、线程调度参数的设置、以及如何安全地fork子进程等。这些高级主题对于开发高性能、高可靠性的多线程应用至关重要。 ...

    Delphi 多线程编程

    ### Delphi 多线程编程知识点 #### 一、Delphi多线程编程概述 在计算机科学领域,多线程编程是一种使程序能够同时执行多个任务的技术。对于使用Delphi进行开发的应用程序而言,实现多线程编程可以显著提高应用程序...

    多线程编程的入门教程

    标题所指的知识点是“多线程编程的入门教程”,这意味着本文档是为那些刚接触多线程编程的初学者提供的基础教学材料。通过这个标题,我们可以推断文档内容会从最基础的多线程概念讲起,逐渐过渡到实际编程技巧和例子...

    iOS 多线程编程指南 pdf

    综合上述内容,iOS多线程编程指南是一份极具价值的资源,它不仅详细介绍了iOS平台下多线程编程的基础知识,还包括了许多编程实践中的技巧和最佳实践,对于iOS开发者来说,是提高开发技能不可或缺的学习资料。

    VC++多线程编程实例

    在VC++编程环境中,多线程技术是一种强大的工具,它...以上就是关于VC++多线程编程的一些关键知识点。通过学习和实践这些实例,开发者可以提升其在并发编程领域的技能,更好地设计和实现高效、稳定的多线程应用程序。

    VC多线程编程

    ### VC多线程编程知识点详解 #### 一、引言:多线程编程的重要性 在软件开发中,尤其是在图形用户界面(GUI)应用领域,如何有效地处理耗时操作成为了一个重要议题。耗时操作(如文件读写、网络请求、复杂计算等)...

    C# 多线程编程实例实战

    C# 多线程编程实例实战 本文探索了 C# 多线程编程实例实战,特别是单个写入程序/多个阅读程序的线程同步问题。在这种情况下,写入程序需要修改共享资源,而阅读程序需要读取数据。为了解决这个问题,需要满足两个...

    Linux多线程编程知识点总结(C语言)(csdn)————程序.pdf

    本文主要围绕Linux下C语言实现的多线程编程进行知识点总结,涉及线程与进程的区别、多线程的优势、Pthreads API以及线程安全和死锁预防。 首先,线程和进程是操作系统中两种基本的执行单元。线程是进程内部的执行流...

    多线程编程中英文对照.rar

    在IT领域,多线程编程是...综上所述,学习Symbian的多线程编程不仅涉及基本的线程概念,还包括线程创建、同步、调度、异常处理以及资源管理等多个方面。这些文档将为开发者提供深入理解和实践这一关键技能的必要知识。

    .NET多线程编程.NET多线程编程

    本文将深入探讨.NET多线程编程的相关知识点,包括线程的创建、同步、互斥与通信,以及如何处理线程安全问题。 1. **线程的创建** 在.NET中,我们可以使用`System.Threading.Thread`类来创建新的线程。通过实例化`...

    QT多线程编程

    ### QT多线程编程知识点详解 #### 一、QT多线程编程背景及支持机制 **QT** 是一种广泛使用的跨平台图形用户界面(GUI)框架,它基于 **C++** 开发,允许开发者轻松构建复杂的图形用户界面系统。为了满足用户在不同...

Global site tag (gtag.js) - Google Analytics