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

java线程的两种创建方法

 
阅读更多

与人有生老病死一样,线程也同样要经历开始(等待)、运行、挂起和停止四种不同的状态。这四种状态都可以通过Thread类中的方法进行控制。下面给出了Thread类中和这四种状态相关的方法。

//开始线程
publicvoidstart();
publicvoidrun();

//挂起和唤醒线程
publicvoidresume();//不建议使用
publicvoidsuspend();//不建议使用
publicstaticvoidsleep(longmillis);
publicstaticvoidsleep(longmillis,intnanos);

//终止线程
publicvoidstop();//不建议使用
publicvoidinterrupt();

//得到线程状态
publicbooleanisAlive();
publicbooleanisInterrupted();
publicstaticbooleaninterrupted();

//join方法
publicvoidjoin()throwsInterruptedException;

一、创建并运行线程

线程在建立后并不马上执行run方法中的代码,而是处于等待状态。线程处于等待状态时,可以通过Thread类的方法来设置线程不各种属性,如线程的优先级(setPriority)、线程名(setName)和线程的类型(setDaemon)等。

当调用start方法后,线程开始执行run方法中的代码。线程进入运行状态。可以通过Thread类的isAlive方法来判断线程是否处于运行状态。当线程处于运行状态时,isAlive返回true,当isAlive返回false时,可能线程处于等待状态,也可能处于停止状态。下面的代码演示了线程的创建、运行和停止三个状态之间的切换,并输出了相应的isAlive返回值。

packagechapter2;

publicclassLifeCycleextendsThread
{
publicvoidrun()
{
intn=0;
while((++n)<1000);
}

publicstaticvoidmain(String[]args)throwsException
{
LifeCyclethread1
=newLifeCycle();
System.out.println(
"isAlive:"+thread1.isAlive());
thread1.start();
System.out.println(
"isAlive:"+thread1.isAlive());
thread1.join();
//等线程thread1结束后再继续执行
System.out.println("thread1已经结束!");
System.out.println(
"isAlive:"+thread1.isAlive());
}
}

要注意一下,在上面的代码中使用了join方法,这个方法的主要功能是保证线程的run方法完成后程序才继续运行,这个方法将在后面的文章中介绍

上面代码的运行结果:

isAlive:false
isAlive:true
thread1已经结束!
isAlive:false

二、挂起和唤醒线程

一但线程开始执行run方法,就会一直到这个run方法执行完成这个线程才退出。但在线程执行的过程中,可以通过两个方法使线程暂时停止执行。这两个方法是suspend和sleep.在使用suspend挂起线程后,可以通过resume方法唤醒线程。而使用sleep使线程休眠后,只能在设定的时间后使线程处于就绪状态(在线程休眠结束后,线程不一定会马上执行,只是进入了就绪状态,等待着系统进行调度)。

虽然suspend和resume可以很方便地使线程挂起和唤醒,但由于使用这两个方法可能会造成一些不可预料的事情发生,因此,这两个方法被标识为deprecated(抗议)标记,这表明在以后的jdk版本中这两个方法可能被删除,所以尽量不要使用这两个方法来操作线程。下面的代码演示了sleep、suspend和resume三个方法的使用。

packagechapter2;

publicclassMyThreadextendsThread
{
classSleepThreadextendsThread
{
publicvoidrun()
{
try
{
sleep(
2000);
}
catch(Exceptione)
{
}
}
}
publicvoidrun()
{
while(true)
System.out.println(
newjava.util.Date().getTime());
}
publicstaticvoidmain(String[]args)throwsException
{
MyThreadthread
=newMyThread();
SleepThreadsleepThread
=thread.newSleepThread();
sleepThread.start();
//开始运行线程sleepThread
sleepThread.join();//使线程sleepThread延迟2秒
thread.start();
booleanflag=false;
while(true)
{
sleep(
5000);//使主线程延迟5秒
flag=!flag;
if(flag)
thread.suspend();
else
thread.resume();
}
}
}

从表面上看,使用sleep和suspend所产生的效果类似,但sleep方法并不等同于suspend.它们之间最大的一个区别是可以在一个线程中通过suspend方法来挂起另外一个线程,如上面代码中在主线程中挂起了thread线程。而sleep只对当前正在执行的线程起作用。在上面代码中分别使sleepThread和主线程休眠了2秒和5秒。在使用sleep时要注意,不能在一个线程中来休眠另一个线程。如main方法中使用thread.sleep(2000)方法是无法使thread线程休眠2秒的,而只能使主线程休眠2秒。

在使用sleep方法时有两点需要注意:

1. sleep方法有两个重载形式,其中一个重载形式不仅可以设毫秒,而且还可以设纳秒(1,000,000纳秒等于1毫秒)。但大多数操作系统平台上的Java虚拟机都无法精确到纳秒,因此,如果对sleep设置了纳秒,Java虚拟机将取最接近这个值的毫秒。

2. 在使用sleep方法时必须使用throws或try{……}catch{……}.因为run方法无法使用throws,所以只能使用try{……}catch{……}.当在线程休眠的过程中,使用interrupt方法(这个方法将在2.3.3中讨论)中断线程时sleep会抛出一个InterruptedException异常。sleep方法的定义如下:

publicstaticvoidsleep(longmillis)throwsInterruptedException
publicstaticvoidsleep(longmillis,intnanos)throwsInterruptedException

三、终止线程的三种方法

有三种方法可以使终止线程。

1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。

2. 使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。

3. 使用interrupt方法中断线程。

1. 使用退出标志终止线程

当run方法执行完后,线程就会退出。但有时run方法是永远不会结束的。如在服务端程序中使用线程进行监听客户端请求,或是其他的需要循环处理的任务。在这种情况下,一般是将这些任务放在一个循环中,如while循环。如果想让循环永远运行下去,可以使用while(true){……}来处理。但要想使while循环在某一特定条件下退出,最直接的方法就是设一个boolean类型的标志,并通过设置这个标志为true或false来控制while循环是否退出。下面给出了一个利用退出标志终止线程的例子。

packagechapter2;

publicclassThreadFlagextendsThread
{
publicvolatilebooleanexit=false;

publicvoidrun()
{
while(!exit);
}
publicstaticvoidmain(String[]args)throwsException
{
ThreadFlagthread
=newThreadFlag();
thread.start();
sleep(
5000);//主线程延迟5秒
thread.exit=true;//终止线程thread
thread.join();
System.out.println(
"线程退出!");
}
}

在上面代码中定义了一个退出标志exit,当exit为true时,while循环退出,exit的默认值为false.在定义exit时,使用了一个Java关键字volatile,这个关键字的目的是使exit同步,也就是说在同一时刻只能由一个线程来修改exit的值,

2. 使用stop方法终止线程

使用stop方法可以强行终止正在运行或挂起的线程。我们可以使用如下的代码来终止线程:

thread.stop();

虽然使用上面的代码可以终止线程,但使用stop方法是很危险的,就象突然关闭计算机电源,而不是按正常程序关机一样,可能会产生不可预料的结果,因此,并不推荐使用stop方法来终止线程。

3. 使用interrupt方法终止线程

使用interrupt方法来终端线程可分为两种情况:

(1)线程处于阻塞状态,如使用了sleep方法。

(2)使用while(!isInterrupted()){……}来判断线程是否被中断。

在第一种情况下使用interrupt方法,sleep方法将抛出一个InterruptedException例外,而在第二种情况下线程将直接退出。下面的代码演示了在第一种情况下使用interrupt方法。

packagechapter2;

publicclassThreadInterruptextendsThread
{
publicvoidrun()
{
try
{
sleep(
50000);//延迟50秒
}
catch(InterruptedExceptione)
{
System.out.println(e.getMessage());
}
}
publicstaticvoidmain(String[]args)throwsException
{
Threadthread
=newThreadInterrupt();
thread.start();
System.out.println(
"在50秒之内按任意键中断线程!");
System.in.read();
thread.interrupt();
thread.join();
System.out.println(
"线程已经退出!");
}
}

上面代码的运行结果如下:

在50秒之内按任意键中断线程!

sleepinterrupted
线程已经退出!

在调用interrupt方法后, sleep方法抛出异常,然后输出错误信息:sleep interrupted.

注意:在Thread类中有两个方法可以判断线程是否通过interrupt方法被终止。一个是静态的方法interrupted(),一个是非静态的方法isInterrupted(),这两个方法的区别是interrupted用来判断当前线是否被中断,而isInterrupted可以用来判断其他线程是否被中断。因此,while (!isInterrupted())也可以换成while (!Thread.interrupted())。

文章转载自:http://java.chinaitlab.com/line/778850.html

分享到:
评论

相关推荐

    在Java中创建线程有两种方法

    Java提供了两种主要的方法来创建线程,分别是直接继承自`Thread`类和实现`Runnable`接口。这两种方法各有其特点和适用场景。 1. **继承Thread类**: 当你选择继承`Thread`类时,你需要创建一个新的类,该类直接...

    java用线程两种方式

    在Java中,创建和使用线程主要有两种方式,一种是继承Thread类,另一种是实现Runnable接口。这两种方式在使用上有一些区别,每种方式都有其特定的用法和特点。 首先,继承Thread类的方式。通过继承Thread类来创建...

    java中创建线程两个方法及区别

    下面将详细阐述这两种创建线程的方法及其区别。 ### 一、通过继承`Thread`类创建线程 当一个类继承了`Thread`类时,它自动获得了`Thread`类的所有功能,包括`start()`和`run()`方法。`start()`方法用于启动线程,...

    java线程.pdf

    线程在Java中可以通过两种方式创建:继承`Thread`类或者实现`Runnable`接口。 #### 继承Thread类 ```java class MyThread extends Thread { public void run() { // 在这里编写线程执行的代码 } } ``` #### ...

    关于线程(java)两天的课件

    在Java中,有两种主要的方式来创建线程:继承Thread类并重写run()方法,或者实现Runnable接口并将其实例传递给Thread构造函数。继承Thread类的方法直接扩展Thread类,而实现Runnable接口则更适合多线程资源共享的...

    Java线程详解大全

    Java线程是并发编程的核心部分,它允许程序在同一时间执行多个独立的任务,从而提高系统效率和响应速度。本文将深入探讨Java线程的概念、生命周期、实现方式以及相关的同步机制。 首先,理解线程的基本概念至关重要...

    Java线程.ppt

    如果你想创建一个新的线程,你可以选择以下两种方式: 1. 继承`Thread`类并重写`run()`方法。 2. 实现`Runnable`接口,创建一个实现该接口的类,然后将其实例传递给`Thread`类的构造函数。 线程有四种基本状态:...

    在Java中创建线程有两种方法.doc

    ### 在Java中创建线程的两种方法 #### 一、概述 在Java中,创建线程主要有两种方式:一种是通过继承`Thread`类来实现;另一种是通过实现`Runnable`接口来完成。这两种方法都能有效地创建并启动线程,但它们各自的...

    java线程深入解析

    创建Java线程有两种方式:继承`Thread`类并重写`run()`方法,或者实现`Runnable`接口并提供`run()`方法。当线程对象被创建并调用`start()`方法后,线程进入可运行态,由Java的线程调度器决定何时执行`run()`方法。 ...

    多线程两种实现方式Java

    本篇将详细讲解Java中实现多线程的两种主要方法:继承Thread类和实现Runnable接口。 ### 继承Thread类 1. **创建子类**:首先,我们需要创建一个新的类,该类继承自Java的`Thread`类。这样,我们的类就拥有了`...

    java线程:两种传统的实现方式.zip

    本文将深入探讨两种传统的Java线程实现方式,并通过一个具体的例子来阐述如何创建和管理这些线程。 首先,我们来看第一种线程实现方式:继承`Thread`类。当你创建一个新的类继承自`java.lang.Thread`,你可以重写它...

    java多线程Demo

    在Java中,实现多线程有两种主要方式:继承Thread类和实现Runnable接口。 1. 继承Thread类: 当我们创建一个新的类,让它继承Thread类时,可以通过重写`run()`方法来定义线程执行的任务。然后创建该类的对象,并...

    Java线程使用教程

    2. **线程的创建**:Java提供了两种创建线程的方式,一是继承`Thread`类并重写`run()`方法,二是实现`Runnable`接口并提供`run()`方法,然后通过`Thread`对象启动。 3. **线程的启动**:通过`start()`方法启动线程...

    Java多线程-对比创建多线程的两种方式

    Java多线程编程中,创建线程主要有两种方式:继承`Thread`类和实现`Runnable`接口。这两种方式虽然都能实现多线程,但它们在实际应用中有着不同的特性和适用场景。 首先,我们来看看继承`Thread`类的方式。这种方式...

    java线程实例 各种小Demo

    Java线程是多任务编程的重要概念,它允许程序同时执行多个独立的任务,从而...在"线程池.rar"和"线程实例"这两个文件中,你可以找到关于这些概念的具体示例代码,通过学习和实践,可以深入理解Java线程的运用和管理。

    java多线程的两种实现

    在Java中,有两种主要的实现多线程的方式:通过`Thread`类和通过实现`Runnable`接口。 1. **通过`Thread`类实现多线程** 当我们创建一个`Thread`类的子类时,可以重写`run()`方法来定义线程执行的任务。例如: ``...

    java多线程代码案例(创建线程,主线程,线程优先级,线程组,线程同步,线程间的通信)

    在Java中,可以通过两种方式创建线程:继承`Thread`类或实现`Runnable`接口。继承`Thread`类时,重写`run()`方法,然后通过`start()`方法启动线程。实现`Runnable`接口则需要创建一个实现了`run()`方法的类,并将...

    JAVA线程的两种创建方式及优劣比较.pdf

    Java线程是多任务编程的重要组成部分,它允许程序同时执行多个任务。在Java中,有以下两种主要的方式来创建和管理线程: 1. **通过实现Runnable接口创建线程** 实现Runnable接口是一种推荐的创建线程的方式,因为...

    Java创建子线程的两种方法

    Java 创建子线程的两种方法是 Java 编程中非常重要的知识点。创建子线程的两种方法主要介绍了 Java 创建子线程的两种方法,通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值。 一、继承 ...

    简单的java线程demo

    本示例"简单的Java线程demo"旨在帮助初学者理解如何在Java中创建和管理线程。 在Java中,有两种主要的方式来创建线程:继承Thread类和实现Runnable接口。下面我们将详细讨论这两个方法。 1. 继承Thread类: 当一个...

Global site tag (gtag.js) - Google Analytics