`
tomotoboy
  • 浏览: 166866 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

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

阅读更多
原文链接:线程对象的几个重要的方法
首先我们接基础篇(二)来说明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,所以

  B b = new B();

  b.start();//做工作B

  A();//做工作A

  b.join();//等工作B完成。

  C();//继续工作C。

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

  yield()方法也是类方法,只在当前线程上调用,理由同上,它主是让当前线程放弃本次分配到的时间片原则:[不是非常必要的情况下,没有理由调用它].调用这个方法不会提高任何效率,只是降低了CPU的总周期
    上面介绍的线程一些方法,基于(基础篇)而言只能简单提及.以后具体应用中我会结合实例详细论述。

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

  [wait(),notify()/notifyAll()]

  这是在多线程中非常重要的方法。
分享到:
评论

相关推荐

    线程的几个重要方法.doc

    本文将详细讲解Java中线程的几个关键方法及其应用场景。 1. `run()`方法 `run()`方法是线程执行的主要逻辑所在。当创建一个线程并调用`start()`方法时,Java虚拟机(JVM)会自动调用`run()`方法。`run()`方法必须是`...

    3种多线程实现同步方法

    在互斥对象.cpp文件中,每个线程在访问共享资源前需要先调用lock()方法获取互斥锁,执行完相关操作后调用unlock()释放锁。这样,任何时刻只有一个线程能够持有互斥锁,从而避免了并发访问冲突。 除了以上三种方法,...

    易语言线程互斥对象解决

    在易语言中,解决线程互斥问题通常涉及以下几个步骤: - 创建Mutex对象:通过特定的函数或命令创建Mutex。 - 请求Mutex所有权:在线程开始访问共享资源前,尝试获取Mutex。 - 保护资源访问:在Mutex被持有的时间...

    线程的几种控制方式以及线程间的几种通信方式

    7. **线程join()**:在Java中,`thread.join()`方法使得当前线程等待指定线程结束再继续执行,Python中没有直接对应的方法,但可以通过`Event`或`Condition`对象实现类似功能。 8. **守护线程(Daemon)**:Java中...

    初始化多线程的几种方法

    在处理多线程时,有几个关键概念和特性需要理解: - **线程同步**:为了避免线程间的冲突,需要同步对共享资源的访问。C#提供了`Mutex`, `Semaphore`, `Monitor`, `lock`等机制。 - **线程优先级**:每个线程都有...

    线程及方法调用

    5. **死亡状态**:线程完成`run()`方法或被强制停止(不推荐使用`stop()`和`destroy()`,这两个方法已过时)。 在Java中,推荐使用`interrupt()`方法来请求线程中断,然后在线程的`run()`方法中检查`isInterrupted...

    QT多线程moveToThread使用方式

    1. **创建线程对象**:首先,你需要创建一个`QThread`对象,这将代表一个新的线程上下文。你可以自定义继承自`QThread`的类,以便在`run()`方法中添加线程特定的逻辑。 2. **重写run方法**:尽管不是必需的,但通常...

    武汉理工大学 面向对象与多线程综合实验 档案管理系统

    【武汉理工大学】的这个【面向对象与多线程综合实验】是一个典型的软件开发项目,旨在让学生深入理解并实践这两种核心技术在实际系统中的应用。在这个实验中,学生将设计并实现一个【档案管理系统】,该系统服务于三...

    C#线程相关几个小程序

    标题 "C#线程相关几个小程序" 涉及到的是C#编程语言中的多线程技术,这是软件开发中非常关键的一个部分,特别是在需要同时处理多个任务或提高程序响应速度时。C#提供了丰富的线程支持,让我们来详细探讨一下相关知识...

    多线程一个类对象一个日志

    在提供的文件列表中,我们可以看到几个cpp和h文件,如`MyLog.cpp`、`MyLog.h`,这可能是实现日志类的代码。`my_object_Thread.cpp`和`my_object_Thread.h`可能是处理线程对象的代码。`win_mythtread.cpp`可能包含了...

    几种方法编写线程代码

    当你调用`start()`方法时,系统会自动创建一个新的线程并执行`run()`方法内的代码。例如: ```java class MyThread extends Thread { public void run() { // 线程执行的代码 } } MyThread thread = new ...

    WinCE线程同步方法

    Windows CE提供了几个等待函数,如`WaitForSingleObject()`用于等待单个事件,`WaitForMultipleObjects()`可以等待多个事件,`MsgWaitForMultipleObjects()`和`MsgWaitForMultipleObjectsEx()`则在等待事件的同时还...

    C#多线程的几个例子

    以下是对"C#多线程的几个例子"中可能涉及的知识点的详细解释: 1. **线程的概念**:线程是操作系统分配CPU时间的基本单位,一个进程可以包含一个或多个线程。在C#中,主线程是程序的入口点,而额外创建的线程可以...

    VC多线程中控制界面控件的几种方法

    ### VC多线程中控制界面控件的几种方法 在VC++(Visual C++)开发环境中,特别是使用MFC(Microsoft Foundation Classes)框架时,处理多线程与GUI(图形用户界面)之间的交互是一个常见的需求。为了确保程序的稳定...

    Qt线程之间通信、线程和进程之间通信实例

    在不同线程中的对象可以相互连接,使得一个线程中的信号能够触发另一个线程中的槽。 1. 使用`QThread`类:创建自定义的线程类继承自`QThread`,并在其中重写`run()`方法执行线程任务。同时,可以通过`moveToThread...

    Java多线程知识点总结

    要启动线程,需要调用线程对象的start方法,这将让线程进入就绪状态。需要注意的是,尽管调用了start方法,但线程何时执行取决于线程调度器。 第二种创建线程的方式是实现Runnable接口并重写run方法。这种方式的...

    JAVA单线程多线程

    单线程的优势主要体现在以下几个方面: 1. **简化程序设计**:由于无需处理多线程间的竞争条件或死锁等问题,因此程序设计更加简单明了。 2. **易于调试**:单线程程序的调试相对容易,因为不存在多个线程之间复杂的...

    C#.NET多线程实例6个(包括多线程基本使用,多线程互斥等全部多线程使用实例)(0520_).rar

    通过创建`Thread`对象并调用其`Start()`方法,可以启动新的线程执行指定的方法。 2. **线程同步与互斥**: 当多个线程访问共享资源时,可能会出现竞态条件,导致数据不一致。为了解决这个问题,C#提供了多种同步...

Global site tag (gtag.js) - Google Analytics