`
yesjavame
  • 浏览: 689558 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

多线程编程 基础篇 (三)

阅读更多

基础篇(三)

线程对象的几个重要的方法

尽管线程对象的常用方法可以通过API文档来了解,但是有很多方法仅仅从API说明是无法详细了解的.

本来打算用一节的篇幅来把线程方法中一些重要的知识说完,但这样下来估计要很常的篇幅,可能要用
好几节才能说把和线程方法相关的一些重要的知识说完.


首先我们接基础篇(二)来说明start()方法.

一个线程对象生成后,如果要产生一个执行的线程,就一定要调用它的start()方法.在介绍这个方法时
不得不同时说明run方法.其实线程对象的run方法完全是一个接口回调方法,它是你这个线程对象要完
成的具体逻辑.简单说你要做什么就你在run中完成,而如何做,什么时候做就不需要你控制了,你只要调
用start()方法,JVM就会管理这个线程对象让它产生一个线程并注册到线程处理系统中(线程栈).


从表面上看,start()方法调用了run()方法,事实上,start()方法并没有直接调用run方法.在JDK1.5以前
start()方法是本地方法,它如何最终调用run方法已经不是JAVA程序员所能了解的.而在JDK1.5中,原来的
那个本地start()方法被start0()代替,另个一个纯JAVA的start()中调用本地方法start0(),而在start()
方法中做了一个验证,就是对一个全局变量(对象变量)started做检验,如果为true,则start()抛出异常,不
会调用本地方法start0(),否则,先将该变量设有true,然后调用start0()

从中我们可以看到这个为了控制一个线程对象只能运行成功一次start()方法.这是因为线程的运行要获
取当前环境,包括安全,父线程的权限,优先级等条件,如果一个线程对象可以运行多次,那么定义一个static
的线程在一个环境中获取相应权限和优先级,运行完成后它在另一个环境中利用原来的权限和优先级等属
性在当前环境中运行,这样就造成无法预知的结果.简单说来,让一个线程对象只能成功运行一次,是基于
对线程管理的需要.


start()方法最本质的功能是从CPU中申请另一个线程空间来执行run()方法中的代码,它和当前的线程是
两条线,在相对独立的线程空间运行,也就是说,如果你直接调用线程对象的run()方法,当然也会执行,但
那是在当前线程中执行,run()方法执行完成后继续执行下面的代码.而调用start()方法后,run()方法的
代码会和当前线程并发(单CPU)或并行(多CPU)执行.

所以请记住一句话[调用线程对象的run方法不会产生一个新的线程],虽然可以达到相同的执行结果,但执
行过程和执行效率不同.


[线程的interrupt()方法,interrupted()和isInterrupted()]

这三个方法是关系非常密切而且又比较复杂的,虽然它们各自的功能很清楚,但它们之间的关系有大多数
人不是真正的了解.

先说interrupt()方法,它是实例方法,而它也是最奇怪的方法,在java语言中,线程最初被设计为"隐晦难懂"
的东西,直到现在它的语义不没有象它的名字那样准确.
大多数人以为,一个线程象调用了interrupt()方法,那它对应的线程就应该被中断而抛出异常,
事实中,当一个线程对象调用interrupt()方法,它对应的线程并没有被中断,只是改变了它的中断状态.
使当前线程的状态变以中断状态,如果没有其它影响,线程还会自己继续执行.
只有当线程执行到sleep,wait,join等方法时,或者自己检查中断状态而抛出异常的情况下,线程
才会抛出异常.

如果线程对象调用interrupt()后它对应的线程就立即中断,那么interrupted()方法就不可能执行.
因为interrupted()方法是一个static方法,就是说只能在当前线程上调用,而如果一个线程interrupt()后
它已经中断了,那它又如何让自己interrupted()?

正因为一个线程调用interrupt()后只是改变了中断状态,它可以继续执行下去,在没有调用sleep,
wait,join等法或自己抛出异常之前,它就可以调用interrupted()来清除中断状态(还会原状)
interrupted()方法会检查当前线程的中断状态,如果为"被中断状态"则改变当前线程为"非中断状
态"并返回true,如果为"非中断状态"则返回false,它不仅检查当前线程是否为中断状态,而且在保证当前线
程回来非中断状态,所以它叫"interrupted",是说中断的状态已经结束(到非中断状态了)

isInterrupted()方法则仅仅检查线程对象对应的线程是否是中断状态,并不改变它的状态.

目前大家只能先记住这三个方法的功能,只有真正深入到多线程编程实践中,才会体会到它们为什么
是对象方法,为什么是类方法.

线程到底什么时候才被中断抛出InterruptedException异常,我们将在提高篇中详细讨论.

[sleep(),join(),yield()方法]

在现在的环节中,我只能先说明这些方法的作用和调用原则,至于为什么,在基础篇中无法深入,只能
在提高篇中详细说明.

sleep()方法中是类方法,也就是对当前线程而言的,程序员不能指定某个线程去sleep,只能是当前线
程执行到sleep()方法时,睡眠指定的时间(让其它线程运行).事实上也只能是类方法,在当前线程上调用.试想
如果你调用一个线程对象的sleep()方法,那么这个对象对应的线程如果不是正在运行,它如何sleep()?
所以只有当前线程,因为它正在执行,你才能保证它可以调用sleep()方法.

原则:[在同步方法中尽量不要调用线程的sleep()方法],或者简单说,对于一般水平的程序员你基本
不应该调用sleep()方法.


join()方法,正如第一节所言,在一个线程对象上调用join方法,是当前线程等待这个线程对象对应的
线程结束,比如有两个工作,工作A要耗时10秒钟,工作B要耗时10秒或更多.
我们在程序中先生成一个线程去做工作B,然后做工作A.

newB().start();//做工作B
A();//做工作A

工作A完成后,下面要等待工作B的结果来进行处理.如果工作B还没有完成我就不能进行下面的工作C,所以

Bb=newB();
b.start();//做工作B
A();//做工作A
b.join();//等工作B完成.
C();//继续工作C.


原则:[join是测试其它工作状态的唯一正确方法],我见过很多人,甚至有的是博士生,在处理一项工作
时如果另一项工作没有完成,说让当前工作线程sleep(x),我问他,你这个x是如何指定的,你怎么知道是100毫秒
而不是99毫秒或是101毫秒?其实这就是OnXXX事件的实质,我们不是要等多长时间才去做什么事,而是当等待的
工作正好完成的时候去做.

yield()方法也是类方法,只在当前线程上调用,理由同上,它主是让当前线程放弃本次分配到的时间片
原则:[不是非常必要的情况下,没有理由调用它].调用这个方法不会提高任何效率,只是降低了CPU的总周期


上面介绍的线程一些方法,基于(基础篇)而言只能简单提及.以后具体应用中我会结合实例详细论述.

线程本身的其它方法请参看API文档.下一节介绍非线程的方法,但和线程密切相关的两[三]个对象方法:
[wait(),notify()/notifyAll()]

这是在多线程中非常重要的方法.

分享到:
评论

相关推荐

    java 多线程编程实战指南(核心 + 设计模式 完整版)

    《Java多线程编程实战指南》这本书深入浅出地讲解了Java多线程的核心概念和实战技巧,分为核心篇和设计模式篇,旨在帮助开发者掌握并应用多线程技术。 1. **线程基础** - **线程的创建**:Java提供了两种创建线程...

    多线程编程实战指南-核心篇

    《多线程编程实战指南-核心篇》是针对Java开发者深入理解并掌握多线程编程的一本实战性书籍。在当今的并发计算环境中,多线程技术是必不可少的知识点,它能够有效地利用多核处理器资源,提高程序的执行效率。本书以...

    java多线程编程实战指南 核心篇 代码

    随着现代处理器的生产工艺从提升...《Java多线程编程实战指南(核心篇)》适合有一定Java语言基础的读者作为入门多线程编程之用,也适合有一定多线程编程经验的读者作为重新梳理知识结构以提升认知层次和参考之用。

    VC多线程编程的常用三种方法

    在VC++环境中,多线程编程是开发高效应用程序的关键技术之一。它允许程序同时执行多个任务,提升系统资源利用率,特别是在处理I/O密集型或计算密集型任务时。本篇文章将详细阐述VC++中实现多线程的三种常见方法:...

    Java多线程编程实战指南 设计模式篇.rar

    在Java编程中,多线程是一项关键技能,它允许程序同时执行多个任务,极大地提高了程序的...通过阅读"Java多线程编程实战指南 设计模式篇.pdf",你将获得更深入的理论知识和实践技巧,为你的编程事业奠定坚实的基础。

    Java多线程编程实战指南核新篇&设计篇&以及和核新篇的案例代码

    《Java多线程编程实战指南》是一本深入探讨Java并发编程的书籍,涵盖了核心篇与设计模式篇。这本书旨在帮助开发者理解和掌握Java平台上的多线程编程,提升系统性能和可扩展性。在Java世界中,多线程是实现并发处理、...

    Java多线程编程实战指南-设计模式篇

    随着CPU 多核时代的到来,多线程编程在充分利用计算资源、提高软件服务质量方面扮演了越来越重要的角色。...《Java多线程编程实战指南(设计模式篇)》适合有一定Java 多线程编程基础、经验的读者。

    java多线程基础篇讲解

    总之,Java多线程基础篇讲解涵盖了多线程编程的基本原理和实践,通过学习这些内容,开发者可以掌握如何在Java环境中创建和管理线程,以及如何优化多线程程序以充分利用系统资源,从而编写出高效的并发应用程序。

    windows多线程编程及例程

    总结来说,《Windows多线程编程及例程》这篇教程是学习Windows环境下多线程开发的宝贵资料,通过理论讲解和实战演练,能够帮助开发者建立起扎实的多线程编程基础,提升软件设计和性能优化的能力。遗憾的是,缺少第四...

    Java多线程编程实战指南+设计模式篇

    本资源“Java多线程编程实战指南+设计模式篇”深入探讨了这两个主题,旨在帮助开发者提升其在并发编程和软件设计上的技能。 **一、Java多线程** 1. **线程基础**:Java中的线程是程序执行的最小单位。Java通过`...

    MFC多线程编程.pdf

    本篇内容将基于《MFC多线程编程.pdf》的部分内容,详细介绍多线程的概念、Win32 API对多线程的支持以及MFC框架下的多线程编程技巧。 #### 二、多线程基础理论 ##### 2.1 问题提出 以一个简单的例子开始——一个名为...

    java编程基础篇 java编程

    学习"JAVA程序员必读基础篇"的内容,将帮助初学者建立起坚实的Java编程基础,为进一步深入学习Java高级特性,如Spring框架、JDBC数据库访问、多线程编程等打下坚实的基础。通过实践和不断练习,你将能够熟练掌握这个...

    linux多线程编程的聊天软件 (论文)

    在本篇论文“Linux下多线程编程的聊天软件”中,作者李杨探讨了如何利用Linux操作系统和多线程编程技术开发一款功能完备的网络聊天软件。在信息时代的背景下,网络聊天工具已经成为日常生活中不可或缺的通讯手段,而...

    多线程编程

    在本篇文章中,我们将深入探讨如何使用Qtcreator进行多线程编程,以及如何实现每秒输出一个内容的功能。 首先,我们要理解多线程的概念。在单线程环境中,程序执行是顺序的,一次只能处理一个任务。而多线程则允许...

    linux_下多线程编程 C语言

    ### Linux 下 C 语言多线程编程实例解析与关键技术点 #### 一、多线程基础知识 在Linux环境下,利用C语言进行多线程编程是一种常见的技术手段,它能够有效地提高程序的并发处理能力,充分利用现代多核处理器的计算...

    网络编程和多线程网络编程和多线程

    三、多线程在网络编程中的应用 1. **并发处理**:在网络编程中,多线程可以同时处理多个客户端连接,提高服务器的并发能力,例如使用线程池处理HTTP请求。 2. **非阻塞I/O**:多线程配合非阻塞I/O模型,可以提高...

    .net 线程详解 基础篇

    .NET线程详解基础篇主要涉及了线程的创建、类型、异步操作、WinForm多线程编程、线程池以及同步策略等多个方面。以下是对这些知识点的详细说明: 1. **怎样创建一个线程**: - 使用`Thread`类:通过创建`Thread`...

    多线程编程——MFC中的多线程开发

    多线程编程能够提高应用程序的效率和响应性,尤其是在进行耗时操作如网络通信、大数据计算或长时间的IO操作时。本篇文章将深入探讨MFC中的多线程开发,帮助初学者理解和掌握这一关键技能。 首先,我们需要了解多...

Global site tag (gtag.js) - Google Analytics